One-Time Purchase Integration - Stellar Contract Settlement
This page is for advanced / cryptocurrency-native companies. If that’s not you, head back to the Quickstart for the standard flows.
This guide walks you through integrating Coinflow checkout to accept one-time credit card purchases with USDC settlement to your whitelisted Stellar Soroban contract.
Prerequisites
Complete these steps before starting the integration.
Create your sandbox account
Register or login to your sandbox merchant account
Generate API keys
Create a sandbox API key for authentication
Add chargeback protection
Add the protection script to every page of your app
Whitelist your Stellar contract
Whitelist your contract address for settlement
Quick Reference
Authorization Headers
| Header | Description |
|---|---|
Authorization |
Your API key from the merchant dashboard |
x-coinflow-auth-wallet |
User’s Stellar wallet address (G-prefixed) |
x-coinflow-auth-blockchain |
Use stellar for Stellar contract settlement |
x-coinflow-auth-session-key |
JWT token authorizing the payer |
Helpful Resources
- How Stellar contract settlement works
- Test card numbers for sandbox
- Checkout webhooks
- Custom branding
Stellar checkout does not support Credits settlement or partial purchases where the customer contributes their own USDC alongside a credit card payment.
Build Your Stellar Transaction
Before integrating checkout, you need to build a stellarTransaction — a base64-encoded XDR string representing your Soroban contract invocation.
Generate TypeScript Bindings
Use the Stellar CLI to generate TypeScript bindings for your contract:
# Use --network mainnet for production
stellar contract bindings typescript \
--network testnet \
--contract-id YOUR_CONTRACT_ID \
--output-dir ./your-contract-client
Build and Encode the Transaction
import {YourContractClient} from './your-contract-client';
// Initialize your contract client
const client = new YourContractClient({
contractId: 'YOUR_CONTRACT_ID',
networkPassphrase: 'Test SDF Network ; September 2015', // Mainnet: 'Public Global Stellar Network ; September 2015'
rpcUrl: 'https://soroban-testnet.stellar.org', // Mainnet: use your Soroban RPC provider
publicKey: sourceAccountPublicKey,
});
// Build the contract invocation
const tx = await client.your_purchase_function({
usdc: 'CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA',
payer: 'CA6F7DX4RBZLENHGLPPTGQA4CRNNH3U6QJ3KD7HQLN46YENHTWJRZUOH',
recipient: customerWalletAddress,
});
// Convert to base64 XDR string
const stellarTransaction = tx.toXDR();
The payer should be the Coinflow checkout contract address:
| Environment | Checkout Contract Address |
|---|---|
| Sandbox | CA6F7DX4RBZLENHGLPPTGQA4CRNNH3U6QJ3KD7HQLN46YENHTWJRZUOH |
| Production | CDUVNW53LTEPPA6SWEGMAV2KJT4YCRECSLRB7XG3KEN3B62YK6HBKG7S |
Choose Your Implementation
Checkout Link
Best for simple integrations. Generate a hosted checkout URL to redirect users or embed in an iframe.
Step 1: Generate the checkout link
curl -X POST https://api-sandbox.coinflow.cash/api/checkout/link \
-H "Authorization: YOUR_API_KEY" \
-H "x-coinflow-auth-wallet: GBCG42WTVWPO4Q6OZCYI3D6ZSTFMO6S2WPUFM3MYO7LEDFCZU3IDALU" \
-H "x-coinflow-auth-blockchain: stellar" \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"subtotal": {
"cents": 500,
"currency": "USD"
},
"blockchain": "stellar",
"stellarTransaction": "AAAAAgAAAABh...(base64 XDR)...",
"chargebackProtectionData": [{
"productType": "inGameProduct",
"productName": "NFT Item",
"quantity": 1,
"rawProductData": {
"description": "A digital collectible on Stellar"
}
}],
"deviceId": "123456789"
}'
{
"link": "https://sandbox.coinflow.cash/stellar/purchase-v2/YOUR_MERCHANT_ID?sessionKey=eyJhbGci..."
}
Step 2: Use the checkout link
Embed in an iframe
<iframe
allow="payment"
src="CHECKOUT_LINK_FROM_STEP_1"
style="width: 100%; height: 600px; border: none;"
/>
Step 3: Handle success events
Listen for payment completion when using an iframe:
window.addEventListener('message', (event) => {
if (typeof event.data === 'string') {
const data = JSON.parse(event.data);
if (data.data === 'success') {
console.log('Payment ID:', data.info.paymentId);
// Handle successful payment
}
}
});
React SDK
Best for React applications. Provides a pre-built checkout component.
Step 1: Install the SDK
npm install @coinflowlabs/react
Step 2: Tokenize checkout parameters
Encrypt checkout parameters to prevent tampering. Call this from your backend.
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/jwt-token \
--header 'Authorization: YOUR_API_KEY' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"webhookInfo": {
"nftId": "123abc"
},
"subtotal": {
"currency": "USD",
"cents": 500
},
"stellarTransaction": "AAAAAgAAAABh...(base64 XDR)...",
"email": "customer@example.com",
"blockchain": "stellar",
"chargebackProtectionData": [{
"productType": "inGameProduct",
"productName": "NFT Item",
"quantity": 1,
"rawProductData": {
"description": "A digital collectible on Stellar"
}
}],
"deviceId": "123456789"
}'
{
"checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Step 3: Render the checkout component
The StellarWallet interface requires address, sendTransaction, signTransaction, and signMessage:
import { CoinflowPurchase } from '@coinflowlabs/react';
function Checkout({ stellarTransaction }: { stellarTransaction: string }) {
const stellarWallet = {
address: "GBCG42WTVWPO4Q6OZCYI3D6ZSTFMO6S2WPUFM3MYO7LEDFCZU3IDALU",
sendTransaction: async (base64Xdr: string) => {
// Sign and submit the transaction to the Stellar network
// Return the transaction hash
return "transaction_hash";
},
signTransaction: async (base64Xdr: string) => {
// Sign the transaction and return the signed XDR
return "signed_base64_xdr";
},
signMessage: async (message: string) => {
// Sign a message for authentication
return "signature";
},
};
return (
<CoinflowPurchase
wallet={stellarWallet}
merchantId="your-merchant-id"
env="sandbox"
blockchain="stellar"
transaction={stellarTransaction}
jwtToken="JWT_TOKEN_FROM_STEP_2"
subtotal={{ cents: 500, currency: 'USD' }}
onSuccess={(paymentId) => {
console.log('Payment successful:', paymentId);
}}
/>
);
}
Step 4: Configure your dashboard
- Customize the UI to match your brand from your dashboard
- Whitelist your domain to prevent unauthorized embedding
API Only
Best for custom checkout UIs. Full control over the payment flow.
Step 1: Get a session key
Authorize the payer with a JWT token.
curl --request GET \
--url https://api-sandbox.coinflow.cash/api/auth/session-key \
--header 'Authorization: YOUR_API_KEY' \
--header 'accept: application/json' \
--header 'x-coinflow-auth-wallet: GBCG42WTVWPO4Q6OZCYI3D6ZSTFMO6S2WPUFM3MYO7LEDFCZU3IDALU' \
--header 'x-coinflow-auth-blockchain: stellar'
{
"key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Session keys expire after 24 hours. Refresh them before expiration.
Step 2: Get pricing totals
Show the customer a quote including all fees.
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/totals/YOUR_MERCHANT_ID \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: SESSION_KEY_FROM_STEP_1' \
--data '{
"subtotal": { "cents": 500 },
"settlementType": "USDC",
"stellarTransaction": "AAAAAgAAAABh...(base64 XDR)..."
}'
{
"card": {
"subtotal": { "cents": 500 },
"creditCardFees": { "cents": 40 },
"chargebackProtectionFees": { "cents": 0 },
"gasFees": { "cents": 5 },
"total": { "cents": 545 }
}
}
Gas fees for Stellar transactions are automatically estimated by simulating your transaction.
Step 3: Tokenize the credit card
Securely collect and tokenize the card number. See PCI-compliant card tokenization for implementation details.
Step 4: Tokenize checkout parameters
Encrypt checkout parameters to prevent tampering.
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/jwt-token \
--header 'Authorization: YOUR_API_KEY' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"webhookInfo": { "nftId": "123abc" },
"subtotal": { "currency": "USD", "cents": 500 },
"stellarTransaction": "AAAAAgAAAABh...(base64 XDR)...",
"email": "customer@example.com",
"blockchain": "stellar",
"chargebackProtectionData": [{
"productName": "NFT Item",
"quantity": 1,
"productType": "inGameProduct",
"rawProductData": {
"description": "A digital collectible on Stellar"
}
}],
"deviceId": "123456789"
}'
{
"checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Step 5: Process the payment
For new cards:
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/card/YOUR_MERCHANT_ID \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: SESSION_KEY' \
--header 'x-coinflow-client-ip: CUSTOMER_IP_ADDRESS' \
--header 'x-device-id: DEVICE_ID_FROM_PROTECTION_SCRIPT' \
--header 'user-agent: CUSTOMER_USER_AGENT' \
--data '{
"subtotal": { "currency": "USD", "cents": 500 },
"jwtToken": "JWT_TOKEN_FROM_STEP_4",
"card": {
"cardToken": "TOKENIZED_CARD_FROM_STEP_3",
"expYear": "30",
"expMonth": "10",
"email": "customer@example.com",
"firstName": "John",
"lastName": "Doe",
"address1": "123 Main St",
"city": "New York",
"zip": "10001",
"state": "NY",
"country": "US"
}
}'
{
"paymentId": "f3fc8a34-680b-4b91-905b-1db5628bbb0e"
}
For saved cards:
Re-tokenize the saved card with CVV first (see card tokenization docs), then:
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/checkout/token/YOUR_MERCHANT_ID \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: SESSION_KEY' \
--header 'x-coinflow-client-ip: CUSTOMER_IP_ADDRESS' \
--header 'x-device-id: DEVICE_ID' \
--data '{
"subtotal": { "currency": "USD", "cents": 500 },
"jwtToken": "JWT_TOKEN_FROM_STEP_4",
"token": "REFRESHED_CARD_TOKEN"
}'
{
"paymentId": "0090c04b-1ae8-4672-a108-32874df36f11"
}
Step 6: Verify the payment (optional)
curl --request GET \
--url https://api-sandbox.coinflow.cash/api/merchant/payments/enhanced/PAYMENT_ID \
--header 'Authorization: YOUR_API_KEY' \
--header 'accept: application/json'
{
"info": {
"firstName": "John",
"lastName": "Doe",
"email": "customer@example.com",
"streetAddress": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
}
}
3DS Authentication
After implementing basic checkout, add 3DS for stronger authentication. Contact Coinflow to enable 3DS on your account.
Complete Checkout with 3DS Challenge
Learn how to add 3DS to your new card and saved card requests
Chargeback Protection
Improve approval rates and reduce fraud by sharing payer events with Coinflow.
Send user events
Track key user actions throughout their journey on your app.
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/events \
--header 'Authorization: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"eventType": "SignUp",
"customerId": "user-123-abc",
"country": "US",
"username": "johndoe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe"
}'
curl --request POST \
--url https://api-sandbox.coinflow.cash/api/events \
--header 'Authorization: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"eventType": "SignIn",
"customerId": "user-123-abc",
"country": "US",
"email": "john@example.com"
}'
Required headers for checkout
When processing payments, include these headers for chargeback protection:
| Header | Description |
|---|---|
x-device-id |
Device ID from the chargeback protection script |
x-coinflow-client-ip |
Customer’s IPv4 address |
user-agent |
Customer’s browser user agent |
On sandbox, use the test partnerId provided by the Coinflow team when configuring the protection script.
Next Steps
Test Your Integration
Use sandbox test cards to verify your implementation
Configure Webhooks
Receive real-time payment notifications
Go Live
Create your production merchant account
API Reference
Explore the complete API documentation