Skip to content

Payment Provider Integration Guide

This guide walks you through integrating a payment provider with Sawabona.

Choosing a Payment Provider

Sawabona supports 7 payment providers. Choose based on your region and requirements:

Provider Best For Regions Currencies
Stripe Global, high volume Worldwide 135+
Adyen Enterprise, multi-currency Worldwide 250+
Flutterwave African markets Africa 30+
PayStack African startups Africa 10+
MercadoPago Latin America LATAM 20+
PagSeguro Brazil focus Brazil BRL, USD
Braintree PayPal integration Worldwide 130+

Step 1: Create Provider Account

Stripe

  1. Go to https://dashboard.stripe.com
  2. Sign up or log in
  3. Navigate to Developers → API Keys
  4. Copy your Secret Key (starts with sk_test_ or sk_live_)
  5. Copy your Webhook Signing Secret (starts with whsec_)

Paddle

  1. Create a free self-serve sandbox account at https://sandbox-login.paddle.com/signup
  2. Generate an API key (Developer Tools → Authentication)
  3. Create a Notification destination (Developer Tools → Notifications) pointing at https://your-domain.com/api/v1/webhooks/paddle and copy its secret (pdl_ntfset_…)

Other Providers

Follow similar steps for Flutterwave and PayStack. Each provider's dashboard has an API credentials section.

Step 2: Configure Environment Variables

Create a .env file in your Sawabona directory:

# Database
SAWABONA_DATABASE__URL=postgresql://user:password@localhost/sawabona

# Encryption key for API secrets (32 bytes, standard or URL-safe base64)
SAWABONA_ENCRYPTION_KEY=<base64-encoded-32-byte-key>

# Stripe (auto-seeded into DB on startup)
SAWABONA_STRIPE_SECRET_KEY=sk_test_your_key_here
SAWABONA_STRIPE_WEBHOOK_SECRET=whsec_your_secret_here

# Other providers (Paddle, Flutterwave, PayStack) are configured via the
# admin API (PUT /api/v1/admin/payments/providers/{provider}) once enabled.

Optional: override the provider API base URL

Each provider crate ships with the canonical production URL as a compiled-in default (e.g. https://api.stripe.com). You can override it per deployment without code changes — useful for staging gateways, regional endpoints, or a mock server in CI:

SAWABONA_PAYMENT__STRIPE__BASE_URL=https://api-staging.example.com
SAWABONA_PAYMENT__PAYSTACK__BASE_URL=...
SAWABONA_PAYMENT__FLUTTERWAVE__BASE_URL=...
SAWABONA_PAYMENT__PADDLE__BASE_URL=https://sandbox-api.paddle.com

When unset (or empty), the provider falls back to its production default URL.

Step 3: Register Payment Provider

Default Build: Stripe Only

Only the StripeProviderFactory is registered at server startup in sawabona-api/src/lib.rs. If SAWABONA_STRIPE_SECRET_KEY is set and stripe_config is empty, the API encrypts and seeds the config into the database automatically.

Registering Additional Providers

Providers are opt-in via cargo features. Build sawabona-api with the providers you run — e.g. --features stripe,paddle or --features all-providers — and set SAWABONA_PAYMENT_PROVIDERS (comma-separated, e.g. stripe,paddle) to register them at startup. A name in the env var that isn't compiled in is rejected with a clear error (no silent skip).

Each provider factory crate lives in sawabona-payments/ (payment-paddle, payment-flutterwave, payment-paystack). Configure each enabled provider's credentials via the admin API (PUT /api/v1/admin/payments/providers/{provider}).

Stripe Product Mapping

To link Stripe prices to Sawabona products (required for automatic license creation from webhooks):

INSERT INTO stripe_product_mappings (id, product_id, stripe_price_id, created_at)
VALUES (gen_random_uuid(), '<sawabona-product-uuid>', 'price_xxx', NOW());

Step 4: Configure Webhooks

Stripe Webhooks

  1. Go to Developers → Webhooks
  2. Click "Add endpoint"
  3. Enter your webhook URL: https://your-domain.com/api/v1/webhooks/stripe
  4. Select events: checkout.session.completed, invoice.payment_succeeded
  5. Copy the signing secret and set as SAWABONA_STRIPE_WEBHOOK_SECRET in .env

When these events are received, Sawabona automatically creates a license by looking up the stripe_price_id in the stripe_product_mappings table.

Paddle Webhooks

  1. Developer Tools → Notifications → New destination
  2. URL: https://your-domain.com/api/v1/webhooks/paddle
  3. Select the subscription.* and transaction.* events you need
  4. Copy the destination secret (pdl_ntfset_…) into the provider config (webhook secret)

Other Providers

Follow similar steps for each provider. Sawabona ships verified webhook handlers for all 4 providers (Stripe, Paddle, Paystack, Flutterwave).

Step 5: Test Integration

Test Mode

All providers support test/sandbox mode. Use test API keys to verify integration:

# Test Stripe integration
curl -X POST http://localhost:8000/api/v1/admin/payments/providers/stripe/test \
  -H "Authorization: Bearer your_token"

# Response should show provider status
{
  "provider": "stripe",
  "status": "healthy",
  "last_check": "2026-01-28T10:30:00Z"
}

Test Webhook

Use ngrok or localtunnel to test webhooks locally:

# Start ngrok
ngrok http 8000

# Update webhook URL in provider dashboard to ngrok URL
# https://abc123.ngrok.io/api/v1/webhooks/stripe

# Trigger test event in provider dashboard
# Sawabona will receive and process the webhook

Step 6: Production Deployment

Secrets Management

Never commit API keys to version control. Use environment variables or secrets manager:

# Using environment variables
export STRIPE_API_KEY=sk_live_your_production_key
export STRIPE_WEBHOOK_SECRET=whsec_your_production_secret

# Using AWS Secrets Manager
aws secretsmanager get-secret-value --secret-id sawabona/stripe

# Using HashiCorp Vault
vault kv get secret/sawabona/stripe

Webhook Configuration

  1. Update webhook URLs to production domain
  2. Use production API keys (not test keys)
  3. Enable webhook signature verification
  4. Monitor webhook delivery logs

Health Checks

Regularly verify provider health:

# Check all providers
curl http://localhost:8000/api/v1/admin/payments/providers \
  -H "Authorization: Bearer your_token"

# Check specific provider
curl http://localhost:8000/api/v1/admin/payments/providers/stripe/test \
  -H "Authorization: Bearer your_token"

Troubleshooting

Issue Solution
401 Unauthorized Check API key is correct and not expired
Webhook not received Verify webhook URL is publicly accessible
Payment declined Check test mode is enabled for test cards
Rate limit exceeded Implement exponential backoff retry logic

Next Steps


Last Updated: 2026-01-28