Skip to main content

Payment Gateway Comparison: Stripe vs Square vs Adyen vs Wise

Created: February 18, 2026 Larry Qu 4 min read

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

Share this article

Scan to read on mobile