> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.coinflow.cash/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server.

# One-Time Purchase Integration - Solana Contract Settlement

> **Warning**
>
> **This page is for advanced / cryptocurrency-native companies.** If that's not you, head back to the [Quickstart](/guides/getting-started/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 Solana program.

## Prerequisites

> **Warning**
>
> Complete these steps before starting the integration.

#### Create your sandbox account

[Register](https://sandbox-merchant.coinflow.cash/register) or [login](https://sandbox-merchant.coinflow.cash/login) to your sandbox merchant account

#### Generate API keys

[Create a sandbox API key](https://sandbox-merchant.coinflow.cash/api-keys) for authentication

#### Add chargeback protection

[Add the protection script](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection) to every page of your app

#### Whitelist your Solana program

[Whitelist your program](https://sandbox-merchant.coinflow.cash/whitelist-request) to receive USDC settlement

## Quick Reference

#### Authorization Headers

| Header                        | Description                                                                                    |
| ----------------------------- | ---------------------------------------------------------------------------------------------- |
| `Authorization`               | Your API key from [the merchant dashboard](https://sandbox-merchant.coinflow.cash/api-keys)    |
| `x-coinflow-auth-wallet`      | User's Solana wallet address                                                                   |
| `x-coinflow-auth-blockchain`  | Use `solana` for Solana contract settlement                                                    |
| `x-coinflow-auth-session-key` | [JWT token](/api-reference/api-reference/authentication/get-session-key) authorizing the payer |

#### Helpful Resources

* [How Solana contract settlement works](/guides/checkout/settlement-locations/settlement-to-contracts/settle-to-solana-contract/implement-settlement-to-solana-contract#how-it-works)
* [Test card numbers for sandbox](/guides/checkout/testing/testing-credit-cards)
* [Checkout webhooks](/guides/developer-resources/webhooks/checkout-webhooks)
* [Custom branding](/guides/developer-resources/custom-branding)

---

## 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

**`Request`**

```bash title="Request"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/checkout/link \
     --header 'Authorization: YOUR_API_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-coinflow-auth-blockchain: solana' \
     --header 'x-coinflow-auth-wallet: USER_WALLET_ADDRESS' \
     --data '{
       "webhookInfo": {
         "depositId": "123-abc-456"
       },
       "subtotal": {
         "currency": "USD",
         "cents": 500
       },
       "settlementType": "Credits",
       "email": "customer@example.com",
       "blockchain": "solana",
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1,
         "rawProductData": {
           "description": "Purchase credits for gameplay"
         }
       }],
       "deviceId": "123456789",
       "supportEmail": "support@yourcompany.com"
     }'
```

**`Response`**

```json title="Response"
{
  "link": "https://sandbox.coinflow.cash/solana/purchase-v2/your-merchant?sessionKey=..."
}
```

### Step 2: Create a redeem transaction

After the payer completes checkout, create a redeem transaction to settle USDC to your contract. Create a base58 encoded transaction for your whitelisted program.

**`Request`**

```bash title="Request"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/redeem \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-coinflow-auth-blockchain: solana' \
     --header 'x-coinflow-auth-wallet: USER_WALLET_ADDRESS' \
     --data '{
       "subtotal": {
         "currency": "USD",
         "cents": 500
       },
       "merchantId": "YOUR_MERCHANT_ID",
       "transaction": "BASE58_ENCODED_TRANSACTION",
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1
       }]
     }'
```

**`Response`**

```json title="Response"
{
  "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEd..."
}
```

### Step 3: Sign and send the transaction

Have the user's wallet sign and send the transaction.

**`Sign Transaction`**

```javascript title="Sign Transaction"
const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
const bs58 = require('bs58');

async function signTransaction(base58Transaction, keypair) {
  const decodedTransactionBytes = bs58.decode(base58Transaction);
  const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
  versionedTransaction.sign([keypair]);
  const serializedTransaction = versionedTransaction.serialize();
  return bs58.encode(serializedTransaction);
}
```

**`Send Transaction`**

```bash title="Send Transaction"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
       "merchantId": "YOUR_MERCHANT_ID",
       "signedTransaction": "SIGNED_BASE58_TRANSACTION"
     }'
```

#### React SDK

Best for React applications. Provides a pre-built checkout component.

### Step 1: Install the SDK

```bash
npm install @coinflowlabs/react
```

### Step 2: Render the checkout component

```tsx
import { CoinflowPurchase, SettlementType, Currency } from '@coinflowlabs/react';
import { Connection, PublicKey } from '@solana/web3.js';

function Checkout({ wallet, connection }) {
  return (
    <CoinflowPurchase
      wallet={{
        publicKey: new PublicKey(wallet.publicKey),
        signMessage: wallet.signMessage,
        sendTransaction: wallet.sendTransaction
      }}
      connection={connection}
      blockchain="solana"
      merchantId="your-merchant-id"
      env="sandbox"
      settlementType={SettlementType.Credits}
      subtotal={{ cents: 500, currency: Currency.USD }}
      email="customer@example.com"
      webhookInfo={{
        productId: "123abc",
        item: "sword"
      }}
      chargebackProtectionData={[{
        productName: "In-Game Credits",
        productType: "inGameProduct",
        quantity: 1,
        rawProductData: {
          productID: "credits-500",
          productDescription: "500 in-game credits"
        }
      }]}
      onSuccess={(paymentId) => {
        console.log('Payment successful:', paymentId);
        // Create redeem transaction after success
      }}
    />
  );
}
```

### Step 3: Create a redeem transaction on success

After the card payment completes, create and submit the redeem transaction.

**`Request`**

```bash title="Request"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/redeem \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-coinflow-auth-blockchain: solana' \
     --header 'x-coinflow-auth-wallet: USER_WALLET_ADDRESS' \
     --data '{
       "subtotal": {
         "currency": "USD",
         "cents": 500
       },
       "merchantId": "YOUR_MERCHANT_ID",
       "transaction": "BASE58_ENCODED_TRANSACTION",
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1
       }]
     }'
```

**`Response`**

```json title="Response"
{
  "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEd..."
}
```

### Step 4: Sign and send the transaction

**`Sign Transaction`**

```javascript title="Sign Transaction"
async function signTransaction(base58Transaction, keypair) {
  const decodedTransactionBytes = bs58.decode(base58Transaction);
  const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
  versionedTransaction.sign([keypair]);
  const serializedTransaction = versionedTransaction.serialize();
  return bs58.encode(serializedTransaction);
}
```

**`Send Transaction`**

```bash title="Send Transaction"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
       "merchantId": "YOUR_MERCHANT_ID",
       "signedTransaction": "SIGNED_BASE58_TRANSACTION"
     }'
```

#### API Only

Best for custom checkout UIs. Full control over the payment flow.

### Step 1: Get a session key

**`Request`**

```bash title="Request"
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-blockchain: solana' \
     --header 'x-coinflow-auth-wallet: USER_WALLET_ADDRESS'
```

**`Response`**

```json title="Response"
{
  "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

> **Warning**
>
> Session keys expire after 24 hours. Refresh them before expiration.

### Step 2: Get pricing totals

**`Request`**

```bash title="Request"
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' \
     --data '{
       "subtotal": { "cents": 500 }
     }'
```

**`Response`**

```json title="Response"
{
  "card": {
    "subtotal": { "cents": 500 },
    "creditCardFees": { "cents": 0 },
    "total": { "cents": 500 }
  }
}
```

### Step 3: Tokenize the credit card

See [PCI-compliant card tokenization](/recipes/recipes/pci-compliant-card-tokenization) for implementation details.

### Step 4: Process the new card payment

**`Request`**

```bash title="Request"
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' \
     --data '{
       "subtotal": { "currency": "USD", "cents": 500 },
       "webhookInfo": {
         "description": "Purchase credits"
       },
       "card": {
         "expYear": "29",
         "expMonth": "10",
         "email": "customer@example.com",
         "firstName": "John",
         "lastName": "Doe",
         "address1": "123 Main St",
         "city": "Chicago",
         "zip": "60606",
         "state": "IL",
         "country": "US",
         "cardToken": "TOKENIZED_CARD"
       },
       "settlementType": "Credits",
       "authentication3DS": {
         "colorDepth": 30,
         "screenHeight": 1000,
         "screenWidth": 2000,
         "timeZone": 5
       },
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1
       }]
     }'
```

**`Response`**

```json title="Response"
{
  "paymentId": "bdc22a87-fb72-4f9d-a445-f26c04c8376c"
}
```

### Step 5: Process saved card payments (returning users)

Re-tokenize the saved card with CVV first (see [card tokenization docs](/recipes/recipes/pci-compliant-card-tokenization)), then:

**`Request`**

```bash title="Request"
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-device-id: 123456789' \
     --data '{
       "settlementType": "Credits",
       "subtotal": { "currency": "USD", "cents": 500 },
       "webhookInfo": {
         "description": "Purchase credits"
       },
       "authentication3DS": {
         "colorDepth": 30,
         "screenHeight": 1000,
         "screenWidth": 2000,
         "timeZone": 5
       },
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1
       }],
       "token": "REFRESHED_CARD_TOKEN"
     }'
```

**`Response`**

```json title="Response"
{
  "paymentId": "e416a462-33a3-4e80-ab8d-ffa2de666a2b"
}
```

### Step 6: Create a redeem transaction

**`Request`**

```bash title="Request"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/redeem \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'x-coinflow-auth-blockchain: solana' \
     --header 'x-coinflow-auth-wallet: USER_WALLET_ADDRESS' \
     --data '{
       "subtotal": { "currency": "USD", "cents": 500 },
       "merchantId": "YOUR_MERCHANT_ID",
       "transaction": "BASE58_ENCODED_TRANSACTION",
       "chargebackProtectionData": [{
         "productType": "inGameProduct",
         "productName": "In-Game Credits",
         "quantity": 1
       }]
     }'
```

**`Response`**

```json title="Response"
{
  "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEd..."
}
```

### Step 7: Sign and send the transaction

**`Sign Transaction`**

```javascript title="Sign Transaction"
async function signTransaction(base58Transaction, keypair) {
  const decodedTransactionBytes = bs58.decode(base58Transaction);
  const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
  versionedTransaction.sign([keypair]);
  const serializedTransaction = versionedTransaction.serialize();
  return bs58.encode(serializedTransaction);
}
```

**`Send Transaction`**

```bash title="Send Transaction"
curl --request POST \
     --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
       "merchantId": "YOUR_MERCHANT_ID",
       "signedTransaction": "SIGNED_BASE58_TRANSACTION"
     }'
```

---

## Chargeback Protection

### Add the protection script

Add the [chargeback protection script](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection) to every page of your app.

### Send user events

Track key user actions throughout their journey.

**`Sign Up`**

```bash title="Sign Up"
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"
     }'
```

**`Sign In`**

```bash title="Sign In"
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"
     }'
```

> **Info**
>
> On sandbox, use the test `partnerId` provided by the Coinflow team when configuring the protection script.

---

## Next Steps

#### [Test Your Integration](/guides/checkout/testing/testing-credit-cards)

Use sandbox test cards to verify your implementation

#### [Configure Webhooks](/guides/developer-resources/webhooks/checkout-webhooks)

Receive real-time payment notifications

#### [Go Live](https://merchant.coinflow.cash/register)

Create your production merchant account

#### [API Reference](/api-reference/api-reference/checkout/card-checkout)

Explore the complete API documentation