Skip to main content
โšก Calmops

Payment Gateway Comparison: Stripe vs Square vs Adyen vs Wise

Introduction

Choosing the right payment gateway impacts your bottom line. With processing fees, feature differences, and integration complexity varying significantly, making an informed choice is critical.

Key Statistics:

  • Average checkout abandonment: 70%
  • Payment failures cost 3-5% of revenue
  • Gateway downtime can cost $100K/hour
  • 30% of users abandon if only one payment method offered

Comparison Matrix

Feature Stripe Square Adyen Wise
Best For Online SaaS In-person + Online Enterprise International
US domestic 2.9% + $0.30 2.6% + $0.10 2.9% + $0.30 0.5-1%
International +1% +1% +0.5% Mid-market rate
Setup Fee Free Free Custom Free
Monthly Fee Free Free Custom Free
API Quality Excellent Good Good Good
Payout Time 2-7 days Instant-2 days Custom 1-2 days

Stripe Integration

Basic Checkout

#!/usr/bin/env python3
"""Stripe payment integration."""

import stripe
from flask import Flask, request, jsonify

app = Flask(__name__)
stripe.api_key = os.environ['STRIPE_SECRET_KEY']

@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
    """Create Stripe Checkout session."""
    
    session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=[{
            'price_data': {
                'currency': 'usd',
                'product_data': {
                    'name': 'Premium Subscription',
                    'description': 'Monthly premium plan'
                },
                'unit_amount': 2999,  # $29.99
                'recurring': {
                    'interval': 'month'
                }
            },
            'quantity': 1
        }],
        mode='subscription',
        success_url='https://example.com/success',
        cancel_url='https://example.com/cancel',
        customer_email=request.json.get('email'),
        metadata={
            'user_id': request.json.get('user_id')
        }
    )
    
    return jsonify({'session_id': session.id})

@app.route('/webhook', methods=['POST'])
def webhook():
    """Handle Stripe webhooks."""
    
    payload = request.data
    sig_header = request.headers.get('Stripe-Signature')
    
    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, os.environ['STRIPE_WEBHOOK_SECRET']
        )
    except ValueError:
        return 'Invalid payload', 400
    except stripe.error.SignatureVerificationError:
        return 'Invalid signature', 400
    
    # Handle events
    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']
        handle_successful_payment(session)
    elif event['type'] == 'customer.subscription.updated':
        subscription = event['data']['object']
        handle_subscription_update(subscription)
    elif event['type'] == 'customer.subscription.deleted':
        subscription = event['data']['object']
        handle_subscription_cancelled(subscription)
    
    return '', 200

Connect (Marketplaces)

# Stripe Connect for marketplaces
@app.route('/create-connected-account', methods=['POST'])
def create_connected_account():
    """Create connected account for seller."""
    
    account = stripe.Account.create(
        type='express',
        country='US',
        email=request.json.get('email'),
        capabilities={
            'card_payments': {'requested': True},
            'transfers': {'requested': True}
        }
    )
    
    return jsonify({'account_id': account.id})

@app.route('/create-account-link', methods=['POST'])
def create_account_link():
    """Create onboarding link for seller."""
    
    account_link = stripe.AccountLink.create(
        account=request.json.get('account_id'),
        refresh_url='https://example.com/reauth',
        return_url='https://example.com/return',
        type='account_onboarding'
    )
    
    return jsonify({'url': account_link.url})

@app.route('/transfer-to-seller', methods=['POST'])
def transfer_to_seller():
    """Transfer payment to seller (minus platform fee)."""
    
    transfer = stripe.Transfer.create(
        amount=9500,  # $95.00
        currency='usd',
        destination=request.json.get('seller_account_id'),
        transfer_group='ORDER_123'
    )
    
    return jsonify({'transfer_id': transfer.id})

Square Integration

Point of Sale

#!/usr/bin/env python3
"""Square POS integration."""

import square
from square.client import Client

client = Client(
    access_token=os.environ['SQUARE_ACCESS_TOKEN'],
    environment='sandbox'
)

def create_payment_link():
    """Create payment link for online checkout."""
    
    response = client.v1.payments.create_payment_link(
        body={
            "idempotency_key": "unique-key-123",
            "order": {
                "line_items": [
                    {
                        "name": "Premium Plan",
                        "quantity": "1",
                        "base_price_money": {
                            "amount": 2999,
                            "currency": "USD"
                        }
                    }
                ]
            },
            "checkout_options": {
                "redirect_url": "https://example.com/success"
            }
        }
    )
    
    return response.body.payment_link.url

def process_pos_payment(source_id, amount):
    """Process payment from POS."""
    
    response = client.payments.create(
        body={
            "source_id": source_id,  # From Square POS SDK
            "idempotency_key": "unique-key-456",
            "amount_money": {
                "amount": amount,
                "currency": "USD"
            },
            "location_id": os.environ['SQUARE_LOCATION_ID']
        }
    )
    
    return response.body.payment

Adyen Integration

#!/usr/bin/env python3
"""Adyen payment integration."""

from Adyen import Adyen

adyen = Adyen()
adyen.client.platform = "test"
adyen.client.api_key = os.environ['ADYEN_API_KEY']

def create_checkout_session():
    """Create Adyen checkout session."""
    
    request = {
        "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
        "amount": {
            "currency": "USD",
            "value": 2999
        },
        "returnUrl": "https://example.com/redirect",
        "paymentMethod": {
            "type": "scheme",
            "encryptedCardNumber": "encrypted_card_number",
            "encryptedExpiryMonth": "encrypted_expiry_month",
            "encryptedExpiryYear": "encrypted_expiry_year",
            "encryptedSecurityCode": "encrypted_cvc"
        },
        "shopperReference": "user_123"
    }
    
    result = adyen.checkout.payments_api.payments(request)
    return result

def handle_webhook(notification):
    """Process Adyen webhook."""
    
    notification_items = notification.get('notificationItems', [])
    
    for item in notification_items:
        notification_request = item.get('NotificationRequestItem')
        
        if notification_request.get('eventCode') == 'AUTHORISATION':
            if notification_request.get('success') == 'true':
                handle_successful_payment(notification_request)
            else:
                handle_failed_payment(notification_request)
        
        elif notification_request.get('eventCode') == 'REFUND':
            handle_refund(notification_request)

Wise (International Payments)

#!/usr/bin/env python3
"""Wise (TransferWise) integration for international payments."""

import requests
from wise import Wise

wise = Wise(os.environ['WISE_API_KEY'])

def create_quote(source_currency, target_currency, amount):
    """Create exchange quote."""
    
    quote = wise.create_quote(
        source_currency=source_currency,
        target_currency=target_currency,
        amount=amount
    )
    
    return quote

def create_transfer(quote_id, recipient_id):
    """Create transfer to recipient."""
    
    transfer = wise.create_transfer(
        quote_id=quote_id,
        target_account=recipient_id,
        reference="Order #123"
    )
    
    return transfer

def get_requirements(country, currency):
    """Get field requirements for country/currency."""
    
    requirements = wise.get_requirements(
        country_code=country,
        currency=currency
    )
    
    return requirements

def createRecipientProfile(details):
    """Create recipient profile for international transfer."""
    
    recipient = wise.create_recipient(
        profile_type='business',
        details=details
    )
    
    return recipient

Decision Guide

When to Choose Each

Scenario Recommended Gateway
SaaS subscription Stripe
E-commerce Stripe or Square
In-person + online Square
Enterprise/Marketplace Adyen
International payments Wise
Multi-currency Stripe + Wise
Complex pricing Adyen

External Resources


Comments