SumUp
SumUp : solution paiements mobile européenne avec terminaux design et APIs simples. Perfect pour PME, restaurants et commerces locaux.
📚 Ressources Complémentaires
📖 Guides Pratiques
⚖️ Comparatifs
SumUp : Paiements Mobile Européens
Qu’est-ce que SumUp ?
SumUp est la solution paiements mobile européenne utilisée par 4M+ commerçants dans 35+ pays. Cette fintech London-based démocratise les paiements cartes avec terminaux design, pricing transparent, setup instantané et ecosystem business tools pour PME, restaurants et commerces locaux European-focused.
🚀 Fonctionnalités Principales
Terminaux Mobile Design
- SumUp Air : terminal sans contact Bluetooth élégant
- SumUp 3G : connectivity indépendante built-in SIM
- SumUp Solo : reader compact smartphone-connected
- SumUp Plus : terminal avancé receipts printer
Business Management App
- Sales analytics : dashboard comprehensive real-time
- Inventory tracking : stock management simple
- Customer database : CRM basique integrated
- Team management : multi-user access control
Payment Processing
- All card types : Visa, Mastercard, Amex, contactless
- Mobile wallets : Apple Pay, Google Pay, Samsung Pay
- Online payments : e-commerce integration basic
- Recurring billing : subscriptions simple
European Focus
- 35+ countries : European coverage extensive
- Local compliance : regulations automatic handling
- Multi-currency : Euro, GBP, CHF, SEK support
- Local support : customer service native languages
💰 Prix et Structure
Terminal Costs
- SumUp Air : €29 one-time purchase
- SumUp 3G : €99 connectivity included
- SumUp Solo : €19 basic reader
- SumUp Plus : €169 premium features
Transaction Fees
- Card payments : 1,69% flat rate European cards
- Contactless/chip : same rate all payment types
- American Express : 2,5% premium cards
- Online payments : 1,9% + €0,25 per transaction
No Hidden Costs
- No monthly fees : pay-per-transaction only
- No setup costs : immediate activation
- No minimum volume : perfect occasional use
- No contract : cancel anytime freedom
Additional Services
- SumUp Invoices : €4,90/month digital invoicing
- SumUp Business Account : €0 business banking
- Next-day payouts : standard no extra cost
- Instant payouts : 1% fee express availability
⭐ Points Forts
💰 Pricing Transparency
Cost structure simple :
- Flat rate 1,69% no volume tiers
- No hidden fees or monthly costs
- Transparent pricing published online
- Competitive rates European market
🎨 Design Excellence
Hardware quality :
- Elegant design award-winning
- Durable construction business-grade
- Compact size portable convenient
- Battery life full-day usage
⚡ Setup Simplicity
Immediate activation :
- 5-minute signup process
- No credit checks required
- Instant account approval
- Same-day shipping available
🇪🇺 European Expertise
Local market knowledge :
- 35+ countries compliance automatic
- Multi-language customer support
- Local banking partnerships
- Regional market understanding
⚠️ Points Faibles
📊 Limited Analytics
Reporting basic :
- Simple sales dashboard only
- No advanced customer insights
- Limited inventory management
- Basic reporting vs competitors
🔌 Integration Limitations
E-commerce features :
- Basic online payment integration
- No native e-commerce platform
- Limited API functionality
- Simple webhook notifications
🎯 Feature Set Basic
Advanced functionality missing :
- No loyalty program native
- No advanced CRM features
- No marketing automation
- No advanced reporting tools
🌍 Geographic Scope
European focus limitations :
- No North America/Asia coverage
- Limited international expansion
- Regional payment methods only
- Currency support European mainly
🎯 Pour Qui ?
✅ Parfait Pour
- PME européennes commerce local/retail
- Restaurants & cafés quick service needs
- Artisans & services mobile payment requirements
- Pop-up shops temporary/seasonal businesses
- Startups cost-conscious payment needs
❌ Moins Adapté Pour
- Large enterprises advanced features needed
- E-commerce pure online-first businesses
- Global businesses international coverage
- Complex operations advanced analytics requirements
- Loyalty-focused retention program needs
📊 SumUp vs European POS Solutions
Critère | SumUp | Square | iZettle |
---|---|---|---|
Hardware Design | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
Pricing Transparency | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
European Coverage | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
Advanced Features | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
Setup Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
🛠️ Configuration & Intégration
SumUp REST API Integration
// SumUp REST API integration
class SumUpService {
constructor(clientId, clientSecret, environment = 'production') {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseURL = environment === 'production'
? 'https://api.sumup.com'
: 'https://api.sumup.com'; // Same URL for sandbox
this.accessToken = null;
}
async authenticate() {
try {
const response = await fetch(`${this.baseURL}/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: this.clientId,
client_secret: this.clientSecret,
scope: 'payments'
})
});
if (!response.ok) {
throw new Error(`Authentication failed: ${response.statusText}`);
}
const data = await response.json();
this.accessToken = data.access_token;
// Auto-refresh token before expiration
setTimeout(() => this.authenticate(), (data.expires_in - 300) * 1000);
return this.accessToken;
} catch (error) {
console.error('SumUp authentication failed:', error);
throw new Error('Authentication failed');
}
}
async createCheckout(checkoutData) {
if (!this.accessToken) await this.authenticate();
try {
const response = await fetch(`${this.baseURL}/v0.1/checkouts`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
checkout_reference: checkoutData.reference || `ORDER_${Date.now()}`,
amount: parseFloat(checkoutData.amount).toFixed(2),
currency: checkoutData.currency || 'EUR',
merchant_code: checkoutData.merchantCode,
description: checkoutData.description || 'Purchase',
return_url: checkoutData.returnUrl || `${process.env.BASE_URL}/payment/success`,
merchant_name: checkoutData.merchantName || 'Your Store'
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Checkout creation failed: ${error.message}`);
}
const checkout = await response.json();
return {
id: checkout.id,
checkout_reference: checkout.checkout_reference,
amount: checkout.amount,
currency: checkout.currency,
status: checkout.status,
date: checkout.date,
merchant_code: checkout.merchant_code,
merchant_name: checkout.merchant_name,
description: checkout.description
};
} catch (error) {
console.error('SumUp checkout creation failed:', error);
throw new Error('Unable to create checkout');
}
}
async getCheckoutStatus(checkoutId) {
if (!this.accessToken) await this.authenticate();
try {
const response = await fetch(`${this.baseURL}/v0.1/checkouts/${checkoutId}`, {
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Checkout retrieval failed: ${response.statusText}`);
}
const checkout = await response.json();
return {
id: checkout.id,
status: checkout.status,
amount: checkout.amount,
currency: checkout.currency,
date: checkout.date,
transactions: checkout.transactions || []
};
} catch (error) {
console.error('SumUp checkout status failed:', error);
throw new Error('Unable to get checkout status');
}
}
async getTransactionHistory(limit = 50, startDate = null, endDate = null) {
if (!this.accessToken) await this.authenticate();
try {
const params = new URLSearchParams({
limit: limit.toString()
});
if (startDate) params.append('oldest', startDate);
if (endDate) params.append('newest', endDate);
const response = await fetch(`${this.baseURL}/v0.1/me/transactions/history?${params}`, {
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Transaction history failed: ${response.statusText}`);
}
const data = await response.json();
return data.map(transaction => ({
id: transaction.id,
transaction_code: transaction.transaction_code,
amount: transaction.amount,
currency: transaction.currency,
timestamp: transaction.timestamp,
status: transaction.status,
payment_type: transaction.payment_type,
entry_mode: transaction.entry_mode,
tip_amount: transaction.tip_amount || 0,
vat_amount: transaction.vat_amount || 0,
payouts_total: transaction.payouts_total,
payouts_fee: transaction.payouts_fee,
username: transaction.username,
card: {
type: transaction.card?.type,
last_4_digits: transaction.card?.last_4_digits
}
}));
} catch (error) {
console.error('SumUp transaction history failed:', error);
throw new Error('Unable to get transaction history');
}
}
async getMerchantProfile() {
if (!this.accessToken) await this.authenticate();
try {
const response = await fetch(`${this.baseURL}/v0.1/me`, {
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Profile retrieval failed: ${response.statusText}`);
}
const profile = await response.json();
return {
merchant_code: profile.merchant_code,
merchant_name: profile.merchant_name,
currency: profile.currency,
country: profile.country,
is_active: profile.is_active,
settings: {
tax_enabled: profile.settings?.tax_enabled,
payout_type: profile.settings?.payout_type,
payout_on_demand_available: profile.settings?.payout_on_demand_available,
daily_payout_email: profile.settings?.daily_payout_email,
monthly_payout_email: profile.settings?.monthly_payout_email
}
};
} catch (error) {
console.error('SumUp profile retrieval failed:', error);
throw new Error('Unable to get merchant profile');
}
}
async processWebhook(webhookBody, signature) {
// SumUp webhook verification would go here
// For now, just log the event
console.log('SumUp webhook received:', webhookBody);
const event = JSON.parse(webhookBody);
switch (event.event_type) {
case 'CHECKOUT_STATUS_CHANGED':
await this.handleCheckoutStatusChange(event.resource);
break;
case 'TRANSACTION_STATUS_CHANGED':
await this.handleTransactionStatusChange(event.resource);
break;
default:
console.log('Unhandled SumUp webhook event:', event.event_type);
}
return true;
}
async handleCheckoutStatusChange(checkout) {
console.log(`Checkout ${checkout.id} status changed to: ${checkout.status}`);
switch (checkout.status) {
case 'PAID':
// Payment completed successfully
await this.handlePaymentSuccess(checkout);
break;
case 'FAILED':
// Payment failed
await this.handlePaymentFailure(checkout);
break;
case 'PENDING':
// Payment in progress
console.log('Payment pending for checkout:', checkout.id);
break;
}
}
async handlePaymentSuccess(checkout) {
console.log('Payment successful for checkout:', checkout.id);
// Update order status
// Send confirmation email
// Trigger fulfillment
// Analytics tracking
}
async handlePaymentFailure(checkout) {
console.log('Payment failed for checkout:', checkout.id);
// Update order status
// Send failure notification
// Trigger retry logic if applicable
}
}
// Usage example
const sumUpService = new SumUpService(
process.env.SUMUP_CLIENT_ID,
process.env.SUMUP_CLIENT_SECRET,
'production'
);
// Create payment checkout
async function createSumUpPayment(orderData) {
try {
const checkout = await sumUpService.createCheckout({
reference: `ORDER_${orderData.id}`,
amount: orderData.total,
currency: 'EUR',
merchantCode: process.env.SUMUP_MERCHANT_CODE,
description: `Order #${orderData.orderNumber}`,
returnUrl: '/payment/success',
merchantName: 'Your Store Name'
});
console.log('SumUp checkout created:', checkout.id);
return {
success: true,
checkout_id: checkout.id,
payment_url: `https://api.sumup.com/v0.1/checkouts/${checkout.id}`,
status: checkout.status
};
} catch (error) {
console.error('SumUp payment creation failed:', error);
return {
success: false,
error: error.message
};
}
}
// Express.js webhook handler
const express = require('express');
const app = express();
app.use(express.raw({ type: 'application/json' }));
app.post('/webhooks/sumup', async (req, res) => {
try {
const signature = req.headers['x-sumup-signature'];
const rawBody = req.body;
await sumUpService.processWebhook(rawBody.toString(), signature);
res.status(200).send('OK');
} catch (error) {
console.error('SumUp webhook processing failed:', error);
res.status(500).send('Webhook processing failed');
}
});
Mobile App Integration
// SumUp Mobile Payment Integration (conceptual)
class SumUpMobileIntegration {
constructor(sumUpService) {
this.sumUp = sumUpService;
this.setupUI();
}
setupUI() {
this.createPaymentButton();
this.setupEventListeners();
}
createPaymentButton() {
const button = document.createElement('button');
button.id = 'sumup-pay-button';
button.className = 'sumup-payment-btn';
button.innerHTML = `
<img src="/images/sumup-logo.png" alt="SumUp" style="height: 20px; margin-right: 8px;">
Pay with SumUp
`;
button.style.cssText = `
background: #1dbccb;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.3s ease;
`;
button.addEventListener('mouseover', () => {
button.style.background = '#17a2b8';
});
button.addEventListener('mouseout', () => {
button.style.background = '#1dbccb';
});
return button;
}
setupEventListeners() {
document.addEventListener('click', (e) => {
if (e.target.id === 'sumup-pay-button') {
this.initializePayment();
}
});
}
async initializePayment() {
try {
// Get order details from page/form
const orderData = this.getOrderDataFromPage();
// Create SumUp checkout
const result = await createSumUpPayment(orderData);
if (result.success) {
// For mobile, you might redirect to SumUp's mobile-optimized checkout
// or integrate with their mobile SDK
this.redirectToSumUpCheckout(result.checkout_id);
} else {
this.showError(result.error);
}
} catch (error) {
console.error('SumUp payment initialization failed:', error);
this.showError('Payment initialization failed. Please try again.');
}
}
getOrderDataFromPage() {
// Extract order information from the current page
return {
id: Date.now(),
orderNumber: Math.floor(Math.random() * 1000000),
total: parseFloat(document.querySelector('#total-amount')?.textContent || '0'),
items: this.getCartItems(),
customer: this.getCustomerInfo()
};
}
getCartItems() {
// Extract cart items from page
const items = [];
document.querySelectorAll('.cart-item').forEach(item => {
items.push({
name: item.querySelector('.item-name')?.textContent,
price: parseFloat(item.querySelector('.item-price')?.textContent || '0'),
quantity: parseInt(item.querySelector('.item-quantity')?.textContent || '1')
});
});
return items;
}
getCustomerInfo() {
return {
name: document.querySelector('#customer-name')?.value || 'Customer',
email: document.querySelector('#customer-email')?.value || '',
phone: document.querySelector('#customer-phone')?.value || ''
};
}
redirectToSumUpCheckout(checkoutId) {
// Redirect to SumUp's hosted checkout page
window.location.href = `https://api.sumup.com/v0.1/checkouts/${checkoutId}`;
}
showError(message) {
const errorDiv = document.createElement('div');
errorDiv.className = 'sumup-error';
errorDiv.style.cssText = `
background: #f8d7da;
color: #721c24;
padding: 12px;
border: 1px solid #f5c6cb;
border-radius: 4px;
margin: 15px 0;
`;
errorDiv.textContent = message;
const container = document.querySelector('#payment-container');
if (container) {
container.prepend(errorDiv);
setTimeout(() => errorDiv.remove(), 5000);
}
}
}
// Initialize mobile integration
document.addEventListener('DOMContentLoaded', () => {
const sumUpMobile = new SumUpMobileIntegration(sumUpService);
// Add payment button to checkout
const checkoutContainer = document.querySelector('#payment-methods');
if (checkoutContainer) {
const payButton = sumUpMobile.createPaymentButton();
checkoutContainer.appendChild(payButton);
}
});
🏆 Notre Verdict
SumUp excellent choix PME européennes cherchant solution paiements simple, design et affordable. Perfect pour commerces locaux prioritizing ease-of-use over advanced features.
Note Globale : 4.0/5 ⭐⭐⭐⭐
- Ease of Use : 5/5
- Hardware Design : 5/5
- Pricing Value : 5/5
- Feature Completeness : 2/5
- European Market Fit : 5/5
🎯 Cas d’Usage Réels
💡 Exemple : Coffee Shop Chain
Mobile payments :
- Quick service : contactless payments fast
- Multiple locations : unified dashboard management
- Staff training : minimal learning curve
- Cost control : predictable 1,69% rate
💡 Exemple : Farmer’s Market Vendor
Mobile commerce :
- Outdoor events : portable terminal weather-resistant
- Battery life : full-day operation
- Instant setup : no complex configuration
- Affordable entry : €29 terminal cost low
💡 Conseil OSCLOAD : SumUp perfect choice PME européennes seeking simple, affordable payment solution. Limited advanced features but excellent core functionality. Alternative Square features complexes ou Stripe online-focus.