Stripe Integration Payments

Each merchant store uses their own independent Stripe account. This guide explains how to connect your Stripe account to start accepting payments directly to your bank account.

Overview

secure.checkout.best uses a per-merchant Stripe model. This means:

Direct Payments: 100% of customer payments go directly to your Stripe account. There are no platform fees or intermediaries.

Key Benefits

FeatureDescription
Direct depositsPayments go straight to your bank account via Stripe
Full controlManage refunds, disputes, and payouts in your Stripe dashboard
Your brandingCustomers see your business name on their statements
Independent accountYour Stripe account is completely separate from other merchants

How It Works

1

Create a Stripe Account

Sign up at stripe.com and complete your business verification

2

Get Your API Keys

Copy your Publishable Key and Secret Key from Stripe Dashboard

3

Connect to Your Store

Enter your keys in the Stripe connection form

4

Start Accepting Payments

Customers can now pay on your store, with funds going to your Stripe account

Getting Your Stripe API Keys

Your API keys are found in your Stripe Dashboard:

  1. Go to dashboard.stripe.com
  2. Click Developers in the left sidebar
  3. Click API keys
  4. Copy both keys (click "Reveal" for the secret key)

API Key Types

pk_live_ or pk_test_ Publishable Key

Used in the browser to collect payment details. Safe to expose publicly.

sk_live_ or sk_test_ Secret Key

Used to create charges and manage your account. Keep this secret!

Security: Your Secret Key is encrypted before being stored. It is never exposed in logs, API responses, or anywhere else. Only our payment system uses it to process transactions.

Connecting Your Stripe Account

To connect Stripe to your store:

GET /stripe/connect?store_id=YOUR_STORE_ID

Opens the Stripe connection form where you enter your API keys.

Query Parameters

ParameterDescription
store_idYour store's unique ID (required)
return_urlURL to redirect after successful connection (optional)

Example

https://secure.checkout.best/stripe/connect?store_id=550e8400-e29b-41d4-a716-446655440000&return_url=https://yoursite.com/dashboard

Check Connection Status

GET /stripe/status/{store_id}

Check if your store has Stripe connected.

Response

{
  "store_id": "550e8400-e29b-41d4-a716-446655440000",
  "has_stripe": true,
  "is_live_mode": true
}

Webhook Setup Required

Important: Webhooks are required for orders to be marked as "paid" after successful payment. Without this, payments will succeed in Stripe but orders will remain in "pending" status.

Webhooks notify our checkout system when a payment succeeds or fails. Each merchant must configure their own webhook in their Stripe dashboard.

Step 1: Create Webhook in Stripe

  1. Log in to your Stripe Dashboard
  2. Navigate to Developers → Webhooks
  3. Click "Add endpoint"
  4. Enter this URL:
    https://secure.checkout.best/webhook/stripe
  5. Select events to listen to:
    • payment_intent.succeeded (required)
    • payment_intent.payment_failed (recommended)
  6. Click "Add endpoint"

Step 2: Copy Webhook Signing Secret

  1. After creating the webhook, click on it to view details
  2. Click "Reveal" next to the Signing secret
  3. Copy the secret (starts with whsec_)

Step 3: Add Secret to Your Store

  1. Go to the Merchant Portal
  2. Click on your store → Payments tab
  3. Find the Webhook Configuration section
  4. Paste your webhook signing secret
  5. Click "Save Webhook Secret"

Test Your Webhook

In Stripe's webhook details page, click "Send test webhook" and select payment_intent.succeeded. You should see a successful delivery response.

Tip: Use Stripe's test mode webhooks while developing. Switch to live mode webhook when you're ready to accept real payments.

Troubleshooting

IssueSolution
Orders stay in "pending" after paymentCheck that webhook is configured and signing secret is saved
Webhook delivery failing with 400Verify the signing secret matches (starts with whsec_)
Webhook delivery failing with 500Check our server logs or contact support
Using test mode but not seeing webhooksMake sure you created webhook in test mode (toggle at top of Stripe dashboard)

API Endpoints

Public Endpoints

EndpointMethodDescription
/stripe/connectGETStripe key entry form
/stripe/status/{store_id}GETCheck if Stripe is configured
/stripe/success/{store_id}GETSuccess page after connection

Internal Endpoints

These require the X-Internal-Secret header:

EndpointMethodDescription
/api/internal/stores/{id}/stripe-statusGETGet Stripe status for a store

BMOS Integration

For BuildMyOnlineStore integration, add a "Connect Payments" button in the merchant dashboard:

Redirect to Stripe Connection

@app.route('/dashboard/connect-payments/<storefront_id>')
def connect_payments(storefront_id):
    storefront = Storefront.query.get_or_404(storefront_id)
    
    return redirect(
        f"https://secure.checkout.best/stripe/connect"
        f"?store_id={storefront.checkout_best_store_id}"
        f"&return_url={url_for('dashboard', _external=True)}"
    )

Check Payment Status

import requests

def check_stripe_status(checkout_best_store_id):
    response = requests.get(
        f"https://secure.checkout.best/api/internal/stores/{checkout_best_store_id}/stripe-status",
        headers={"X-Internal-Secret": os.environ["CHECKOUT_BEST_SECRET"]}
    )
    return response.json()

# Usage
status = check_stripe_status(storefront.checkout_best_store_id)
if status.get("has_stripe"):
    print("Store can accept payments!")
else:
    print("Store needs to connect Stripe")

Payment Flow

1

Customer Adds to Cart

Widget creates cart using merchant's store ID

2

Checkout Session Created

Secure token generated for checkout page

3

Payment Form Loads

Stripe.js initialized with merchant's publishable key

4

PaymentIntent Created

Server creates PaymentIntent using merchant's secret key

5

Payment Confirmed

Funds go directly to merchant's Stripe account

Test vs Live Mode

Mode Key Prefix Real Money? When to Use
Test pk_test_, sk_test_ No Development, testing checkout flow
Live pk_live_, sk_live_ Yes Production, real customer payments

Test Card Numbers

When using test mode, use these card numbers:

Card NumberResult
4242 4242 4242 4242Successful payment
4000 0000 0000 0002Card declined
4000 0000 0000 9995Insufficient funds
Tip: Use any future expiration date, any 3-digit CVC, and any ZIP code when testing.

Troubleshooting

Common Issues

"Store not connected to Stripe"

The merchant hasn't entered their Stripe API keys yet. Redirect them to the connection form.

"Invalid API key"

The keys may have been regenerated in Stripe Dashboard. The merchant needs to re-enter their current keys.

"Payment failed"

Check the Stripe Dashboard for the specific error. Common causes:

Payments not showing in dashboard

Make sure you're viewing the correct mode (Test vs Live) in your Stripe Dashboard.

Security

Encryption: All Stripe secret keys are encrypted using Fernet (AES-128-CBC) before being stored in the database. The encryption key is stored separately as an environment variable.

Security Measures

MeasureDescription
Encrypted at restSecret keys are never stored in plaintext
Per-request isolationEach payment uses the correct merchant's keys (no global state)
Key validationKeys are verified against Stripe API before saving
No loggingSecret keys are never written to logs
HTTPS onlyAll API calls are encrypted in transit

Need help? Contact support or visit the Stripe Dashboard