Initialize payment
Initialize a payment transaction with HMAC signature verification and idempotency protection.
π HMAC Signing (REQUIRED)
All payment initialization requests MUST include HMAC-SHA256 signature:
- Generate Timestamp: Get current Unix timestamp in seconds
- Create Payload: Concatenate
timestamp + "." + JSON_body - Sign Payload:
HMAC-SHA256(hmac_secret, payload)β base64 encode - Include Headers:
X-Timestamp: Unix timestamp (must be within 5 minutes)X-Signature: Base64-encoded HMAC signatureIdempotency-Key: Unique key to prevent duplicate payments
π Idempotency Protection (REQUIRED)
Include Idempotency-Key header to prevent duplicate payment initialization.
If the same key is used, the original payment initialization is returned.
- Recommended format:
payment-{timestamp}-{random} - Must be unique per payment attempt
- Prevents duplicate charges on network retries
- Returns existing payment if key already used
π‘οΈ Amount validation (anti-tampering)
When you pass an order_id, the server validates amount against that orderβs authoritative
total β a amount that doesnβt match the order total is rejected with 400 amount_mismatch.
The order total was itself validated against the catalog + the shopperβs real promotions/gift card
at order creation (see the order endpointβs server-side price validation), so you cannot charge
less than the order is worth. Pass the orderβs real total_amount; donβt compute or alter it
client-side.
Provider-Specific Flows:
Stripe (redirect):
- Initialize payment with amount, currency, email
- Redirect customer to
checkout_url - Customer completes payment on Stripe
- Stripe redirects to success/cancel URL
- Verify payment status with
/v1/payments/verify
PayPal (popup):
- Initialize payment with amount and currency
- Use the returned
client_idandpaypal_order_idto render the PayPal Buttons popup in your frontend - Customer approves the payment in the PayPal window
- Verify payment status with
/v1/payments/verifyβ this captures the approved order
Paystack (popup):
- Initialize payment with amount, currency, email
- Use returned
public_keyandreferenceto open Paystack popup - Customer completes payment in popup
- Verify payment status with
/v1/payments/verify
M-Pesa (STK Push):
- Initialize payment with amount and phone (254XXXXXXXXX format)
- Customer receives STK Push prompt on their phone
- Customer enters M-Pesa PIN
- Verify payment status with
/v1/payments/verify
Security Notes:
- HMAC secret is displayed in the Integrations page (Developer section)
- Never expose HMAC secret in client-side code
- Regenerate secret immediately if compromised
- Requests with invalid/missing signatures return 401 Unauthorized
- Timestamps older than 5 minutes are rejected (prevents replay attacks)
Rate Limiting:
- Additional 100 requests/hour limit for payment initialization
- Separate from global API rate limits
Key Type Support:
- β Secret keys (full access)
- β Publishable keys (forbidden - returns 403)
Authorizations
API Key Authentication
Use your API key in the Authorization header:
Key Types:
Secret Keys (Server-Side Only):
- Format:
tybrite_sk_live_*(production) ortybrite_sk_test_*(sandbox) - Full read/write access to all endpoints
- β οΈ NEVER expose in client-side code or public repositories
- Required for: write operations, authentication, payment verification, AI recommendations
Publishable Keys (Client-Safe):
- Format:
tybrite_pk_live_*(production) ortybrite_pk_test_*(sandbox) - Read-only access (GET requests only, plus POST semantic search)
- β Safe for client-side JavaScript, mobile apps, and public code
- Allowed for: browsing products, search, CMS content, pricing queries
Endpoint-Specific Requirements:
- Authentication endpoints (
/v1/auth/*): Secret key required - Payment verification (
POST /v1/payments/verify): Secret key required - AI Recommendations (
POST /v1/recommendations): Secret key required - Semantic Search (
POST /v1/search): Both key types allowed (read-only operation) - All write operations: Secret key required
- All read operations: Both key types allowed
Using a publishable key for restricted operations returns 403 Forbidden.
Headers
Unique key to prevent duplicate payment initialization (e.g., payment-{timestamp}-{random}). If you retry a request with the same key, the original payment initialization is returned.
Unix timestamp in seconds (current time). Must be within 5 minutes of server time. Used to prevent replay attacks.
HMAC-SHA256 signature of the payload (timestamp + "." + request_body), base64-encoded. Sign using your HMAC secret from the Integrations page (Developer section).
Body
Payment provider to use. The built-in providers are stripe, paypal, paystack,
and mpesa. A store that has connected its own payment provider can also pass that
provider's identifier here β the same value returned as provider (with
custom_provider: true) by GET /v1/payments/methods.
"stripe"
Payment amount in MAJOR currency units β 100.00 is one hundred dollars, not one
dollar. This matches every other amount in the API: catalog prices, order totals
and refunds are all major units. Conversion to a processor's minor units (Stripe
cents, Paystack kobo) happens server-side; never send minor units here.
When order_id is supplied the amount must equal that order's total to the cent,
or the request is rejected with amount_mismatch. Sending 10000 for a 100.00
order fails that check rather than charging a hundred times over.
x >= 0.01100
Currency code (ISO 4217). Case-insensitive β it is normalised to whatever the
chosen processor expects, so usd and USD behave identically.
Required for Stripe and Paystack.
- Stripe: Defaults to store's default currency
- PayPal: Defaults to store's default currency
- Paystack: Must be one of NGN, GHS, ZAR, KES, USD
- M-Pesa: Always KES (ignored)
"usd"
Customer email (required for Stripe and Paystack)
"john.doe@example.com"
Customer phone number (required for M-Pesa)
- M-Pesa: Format 254XXXXXXXXX (Kenya)
"254712345678"
ISO 3166-1 alpha-2 country code for the payer. Passed through to a payment method the merchant has added themselves, which may use it to offer the local payment options for that country. The built-in methods ignore it.
"US"
Optional order ID to link payment to an order
"880e8400-e29b-41d4-a716-446655440003"
Optional idempotency key to prevent duplicate payments
"pay-2026-02-10-abc123"
Optional metadata to attach to the payment
Redirect URL after successful payment (Stripe only)
"https://example.com/payment-success"
Redirect URL after cancelled payment (Stripe only)
"https://example.com/payment-cancelled"
Webhook callback URL (Paystack only)
"https://example.com/webhooks/paystack"
Response
Payment initialized successfully
- Option 1
- Option 2
- Option 3
- Option 4
true
"stripe"
"redirect"
"PAY-12345678-ABC123"
"https://checkout.stripe.com/c/pay/..."
"cs_test_..."
"test"

