Powered by Coinflow
Payments · Documentation
Operational

Credit Purchases — Settle to Coinflow Wallet

Setup

Complete account setup first

This integration assumes you’ve completed the Account Setup prerequisites — sandbox merchant account, API key, team access, and any product-specific configuration (settlement location, chargeback protection, or wallet funding).

Developer Resources

Quick Links:

Authorization Headers:

  • Authorization — Your API key from the merchant dashboard.
  • x-coinflow-auth-user-id — A unique customer ID from your own systems identifying the payer or payee.
  • x-coinflow-auth-session-key — A JWT that authorizes the payer. Valid for 24 hours; refresh after expiry.
  1. Share payer events with Coinflow
    Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.
    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": "therock72",
      "email": "dwaynejohnson@gmail.com",
      "firstName": "Dwayne",
      "lastName": "Johnson"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOU_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignIn",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignInFailure",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com",
      "failureReason": "Password Failed"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "BuyerChallenge",
      "type": "thirdPartyKyc",
      "status": "successfullyFulfilled",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
  2. Get a checkout link
    This endpoint will generate a link which you can embed in an iframe or redirect users directly to.
    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-user-id: user-123-abc' \
         --data '
    {
      "webhookInfo": {
        "example": "{\"depositId\": \"123-abc-456\"}"
      }, // Add any webhook info you want to receive here
      "subtotal": {
        "currency": "USD",
        "cents": 100
      },
      "settlementType": "Credits",
      "email": "user@gmail.com", // the purchasers email address
      "chargebackProtectionData": [
        {
          "productType": "", // Get this value from Coinflow after completing chargeback protection questionnaire
          "rawProductData": {
            "example": "{\"description\": \"something about the purchase\"}"
          }, // Pass as much descriptive data detailing the purchase.
          "productName": "Product Name",
          "quantity": 1
        }
      ],
      "deviceId": "123456789", // Get this from: /guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection
      "supportEmail": "support@mycompany.com"
     	}
    '
    {"link":"https://sandbox.coinflow.cash/purchase-v2/testtest?sessionKey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzE5MDQsImV4cCI6MTczNzc1ODMwNH0.zpCD3yH6eeEQHfDHzj2lLeD4-irLz61bgcwcp0gTi_Y&cents=100&currency=USD&customerInfo=N4IgdghgtgpiBcIAiB3CBPMMAEApA9gBZgDO%2BYIANCAG4wBOAlgGaMDGEALo%2BQJIAmCECU5MADjAC0dJqw7dykxv0kBGAEwBmACwBWKiH6MSYgDYYActDiJOhBvjYBrAOzqDEfv3owSJIQAcutgAotgA6hDODAZsjJzoQgDChOwQAOb4BiJcNiC8ADIGAF6MYkIAbAAM1aqx%2BACuYKKJiACqAMoGZUIamgB0fYNaw5oG5pxC2qr9AQEuAeNg6YEu-RXqutogAL5AA&email=user%40gmail.com&jwtToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguCngOaMgeGgleiEg-OAh8iO7IGm0IXjj4DYvOeCqO6XkNOG6ZGy5IC246Oh4pCA5qGE4oC70ILngInugIHsgIvqhJpEyJroupPQgualse2HpOyegOCspkzko6Hih4Dhhp_mtaLokLTqi47ohLbomInuvqXmoZ3hjKTuobPimpjmmqHokofriJDqiKHjgpHjiavmoarWhOKHguGEoe6ImOqDkOKCouGDoeOKpeKGkuGnoeyCouaDouqXg-ShqeKImOatieKJlOmEouaImuqjk-aulO2DouOksuGlu-qoklx1ZGE2MOqGuOaqqeKDkumQoOmOoOakqOatqeuLteODkeOJo-Smq-OJhOGFuuGOmuWZo-qhqO2Okdeg66ib7Zmq76iZ4aK77pSh4oGG5oKQ5rOg5qGp6YKi676j6ZKi4aKR4qmp7ISz6L2I7oqH4qaY5K-h5IyK7qOw7Yif4KyD4qGi4aKU5KCv5Ii96LeA5pGh7JSW6JGp45KX6r6C7YSg5YmV55CK4Yii7IWL6oO07pCw6q2HzYHimrTko4fioazlvYfkmIftlbzjoanjmofcgeyCkO6DpOO2k-GzhOybkei2jOC1iuSIg-SegeSMqe6YpOGote2el-6couOCkOGouOC0ieaTgeaOoeuEg-SCjeGFpueWsuGGvOqNseiIkO6pi-aNqO-UseamluWLmuGHheOGteW5t-KAr-C4quGQoumHmuSwo-WPruiCl-2JieyVuei0vuGGo-Cki-OApOyduuiEjOmJo-SnheGnp-u5kuKKh-2eqeyYm-a0oeGMgemLi-e0sO-pg-KiqeS2p-eio-CzmuWFrumSluSEr-SOpu-hgeW4ku2Ml-Ojq8WX4pmn5IKA7J6N5LGI55Wt4rmB5YmA7YOh7qyK76uC7YGY5Imk56Gu45Gl56-e7ria7IqE76mG4YKV5IKm7Y-15oej5pGY6Liq67GG6Y-m446k4KSE5KiV4L2I5rCy7r2p4by74KOx6ri05JC85ouj5KCp4KSH7Yma66qP4pWT5omR6LiF5aKw5KSJ4pCy5aGh4YuJ6aOE76iR3ILmgIbiu4_jiozkirHoiYDlgo7hraPmh6DhhIPusLPkoaPjga7qgornqJrgsLHvqZXisq7ro6DqlqXik7Dmm6fio4DsgYpcdWQ4YWXqp4flo7noqo3nj6rupqfhhqLho6vokpXjroHvnLjivpjho7Lrpovui7TqvL_ogaLloYjqi43qhKjstJfsjovti7PojITpr6jhmL0w6YOa45qH5IiK7La46q2E7qmjyIDljJTriZfor6LRruG2nuGkpOGQtu68huGru-Cyn-Snuuy8suChg-ipsuqYi-uEsOOYheiHo-qDs-qshumlpOKEsuS-ouqAguqOqOiDjuegleSNg-GQkuOOiO2FoOCsm-ifkO6roeq7i-iGlFx1ZGUzZOmzs--psMOA666Y5paL4KKB4LuR5IiE7Iiu4YqE6p2J47C04oSM5Yia4aC35JqD6Km64bOP7ZOi6ryG5JG47ZG05oiC6Imo5KGGXHVkY2Mw5YKM46Gj7Ka15pSO6K2k66Ko4LeB74eK4paz5oKQ5KmF55OG6YeQ47ik4ZOR44u-4Yiu2LrgvpvlvoHqkYTnsYLsipbssLfkmYPnsKrrpI3miKDskIDqqZnosovrvKfrh7zvsrzuroLhs4bjtobgspDptp7kgZDrgrrpk6TohqTosLronZDvlZDmqZXlrbLjqJTitbfho7TjiIbkh6DQnMiAwr7kgIAiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpZGVtcG90ZW5jeUtleSI6IklLYmNhNjg5OWUtNTY0NS00MTQ2LWIyMzUtNDdiMjNmMjlkY2QzIiwic3VidG90YWwiOnsiY3VycmVuY3kiOiJVU0QiLCJjZW50cyI6MTAwfSwiaWF0IjoxNzM3NjcxOTA0LCJleHAiOjE3Mzc3NTgzMDR9.GP4zCoLBpw8hKiLrU-0WZtxMh_6GPJYvICUjsw-QQjw"}
  3. Submit a purchase through the provided link and go to the merchant dashboard to see the purchase record.

    📘 At this point, the purchase for credits is complete, and the payer has credits in their wallet.

    After the user has credits, they can use their credits for use at anytime.

  4. With Coinflow Wallet, Coinflow manages the payer balance — no signed redemption is required from the merchant for the standard flow.

Advanced: Custom Redemption

Merchants who want full control over redemption can create and sign a redeem transaction themselves.

  1. Create a redeem transaction.

    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/redeem/merchant \
         --header 'accept: application/json' \
         --header 'content-type: application/json' \
         --header 'x-coinflow-auth-blockchain: solana' \
         --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \
         --data '
    {
      "subtotal": {
        "cents": 500
      },
      "merchantId": "YOUR_MERCHANT_ID"
    }
    '
    {
      "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
    }
  2. Sign the transaction with the merchant wallet and submit it via Coinflow’s endpoint to settle the redemption.

    const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
    const bs58 = require('bs58');
    
    const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
    const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
    const privateKey = bs58.decode(privateKeyString);
    const keypair = Keypair.fromSecretKey(privateKey);
    const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3
    
    // return a signed tx
    async function signTransaction() {
      try {
        const decodedTransactionBytes = bs58.decode(base58Transaction);
        const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
        versionedTransaction.sign([keypair]); // wallet signs tx
        const serializedTransaction = versionedTransaction.serialize();
        const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58
    
        console.log(signed tx:', signedTransaction);
        return base58SignedTransaction; // This is what youll send to settle the redemption
    
      } catch (err) {
        console.error('Error signing the transaction:', err);
      }
    }
    
    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": "testtest",
      "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT"
    }
    '

React SDK Implementation

  1. Share payer events with Coinflow
    Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.

    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": "therock72",
      "email": "dwaynejohnson@gmail.com",
      "firstName": "Dwayne",
      "lastName": "Johnson"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOU_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignIn",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignInFailure",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com",
      "failureReason": "Password Failed"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "BuyerChallenge",
      "type": "thirdPartyKyc",
      "status": "successfullyFulfilled",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
  2. Install the Coinflow React package

    npm i @coinflowlabs/react
  3. Render the CoinflowPurchase component to let a customer buy credits with their card or bank account. With the Coinflow Wallet path, no additional wallet or chain configuration is needed.

    import {CoinflowPurchase} from '@coinflowlabs/react';
    
    <CoinflowPurchase
      merchantId="YOUR_MERCHANT_ID"
      env="sandbox" // or "prod"
      email="user@example.com"
      subtotal={{currency: 'USD', cents: 100}}
      settlementType="Credits"
      onSuccess={(...args) => {
        console.log('Purchase Success', args);
      }}
      webhookInfo={{
        productId: '123abc',
        item: 'sword',
      }}
      chargebackProtectionData={[
        {
          productName: 'Product Name',
          productType: 'gameOfSkill', // Get this from Coinflow after completing the chargeback questionnaire
          quantity: 1,
          rawProductData: {
            description: 'pass any product details that help support chargeback responses',
          },
        },
      ]}
    />
  4. Add chargeback protection on every page of your app — required.

With the Coinflow Wallet path, Coinflow manages the credit balance for you. When a customer spends credits, your backend deducts from their balance and you call Coinflow when you need to draw against the settled funds. No client-side wallet signing is needed.

Advanced: Custom client-signed redemption

Merchants who want full control over redemption can pass a pre-built, base58-encoded transaction to CoinflowPurchase via the transaction prop, along with the chain wallet adapter props (wallet, connection, blockchain). Only pass the transaction when the customer is redeeming credits — never on initial purchase. See Custom Redemption below in the API section for the redemption-transaction creation flow.

API Implementation

  1. Share payer events with Coinflow
    Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.

    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": "therock72",
      "email": "dwaynejohnson@gmail.com",
      "firstName": "Dwayne",
      "lastName": "Johnson"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOU_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignIn",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "SignInFailure",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com",
      "failureReason": "Password Failed"
    }
    '
    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/events \
         --header 'Authorization: YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "eventType": "BuyerChallenge",
      "type": "thirdPartyKyc",
      "status": "successfullyFulfilled",
      "customerId": "user-123-abc",
      "country": "US",
      "email": "dwaynejohnson@gmail.com"
    }
    '
  2. Generate an API Key from Merchant Dashboard > API Keys > Create.

  3. Get a Session Key
    This creates a JWT for the payer and must be refreshed every 24 hours.

    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-user-id: user-123-abc'
    {
      "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY"
    }

    Note: Session keys are valid for 24 hours and must be refreshed upon expiration.

  4. Get the Totals for the checkout
    This will return the total price inclusive of all fees for the purchase.

curl --location '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: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--data '
{
  "subtotal": {
    "cents": 200
  }
}
'
//Response
{
    "card": {
        "subtotal": {
            "cents": 200
        },
        "creditCardFees": {
            "cents": 0
        },
        "chargebackProtectionFees": {
            "cents": 0
        },
        "gasFees": {
            "cents": 0
        },
        "total": {
            "cents": 200
        },
        "merchantPaidCreditCardFees": {
            "cents": 36
        },
        "merchantPaidGasFees": {
            "cents": 0
        },
        "merchantPaidChargebackProtectionFees": {
            "cents": 0
        }
    },
    "ach": {
        "subtotal": {
            "cents": 200
        },
        "creditCardFees": {
            "cents": 0
        },
        "chargebackProtectionFees": {
            "cents": 0
        },
        "gasFees": {
            "cents": 0
        },
        "total": {
            "cents": 200
        },
        "merchantPaidCreditCardFees": {
            "cents": 100
        },
        "merchantPaidGasFees": {
            "cents": 0
        },
        "merchantPaidChargebackProtectionFees": {
            "cents": 0
        }
    }
}
  1. Tokenize the Credit Card Number. See tab: Tokenize New Card
  2. Enable a New Card Checkout
    This endpoint will enable a new user who has never made a purchase to complete their purchase using the tokenized credit card retrieved from Step 4. Below is an example of how you’d call the card checkout endpoint:
curl --location 'https://api-sandbox.coinflow.cash/api/checkout/card/testtest' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--data-raw '
{
  "subtotal": {
    "currency": "USD",
    "cents": 100
  },
  "webhookInfo": {
    "example": "{\"description\": \"whatever webhooks info you want to receive\"}"
  }, // pass whatever webhook info you want to receive
	"card": {
    "expYear": "29",
    "expMonth": "10",
    "email": "dwayne@therock.com",
    "firstName": "dwayne",
    "lastName": "johnson",
    "address1": "123 Rock Road",
    "city": "Chicago",
    "zip": "60606",
    "state": "IL",
    "country": "US",
    "cardToken": "230377JSUM3F0275" // Get this from: /recipes/recipes/pci-compliant-card-tokenization
  },
  "settlementType": "Credits",
  "authentication3DS": {
    "colorDepth": 30,
    "screenHeight": 1000,
    "screenWidth": 2000,
    "timeZone": 5
  }, // Get this from: /recipes/complete-checkout-with-3ds-challenge
  "chargebackProtectionData": [
    {
      "productType": "inGameProduct", // Get this after completing chargeback protection questionnaire
      "rawProductData": {
        "example": "{\"description\": \"pass data about the purchase\"}"
      },
      "productName": "Product Name",
      "quantity": 1
    }
  ]
}
'
{"paymentId":"bdc22a87-fb72-4f9d-a445-f26c04c8376c"}
  1. Re-tokenize a saved card number. See tab: Refresh Token w/ CVV
  2. Enable a Saved Card Checkout
    This endpoint will enable a returning user to complete a purchase with a previously saved card. The returning user will need to enter their CVV before confirming the purchase.
    Once you’ve retrieved the refreshed card token, pass it into the Saved Card Checkout endpoint. Below is an example request:
curl --location 'https://api-sandbox.coinflow.cash/api/checkout/token/testtest' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--header 'x-device-id: 123456789' \
--data '
{
  "settlementType": "Credits",
  "subtotal": {
    "currency": "USD",
    "cents": 100
  },
  "webhookInfo": {
    "example": "{\"description\": \"whatever webhooks info you want to receive\"}"
  },
  "authentication3DS": {
    "colorDepth": 30,
    "screenHeight": 1000,
    "screenWidth": 2000,
    "timeZone": 5
  },
  "chargebackProtectionData": [
    {
      "productType": "gameOfSkill",
      "rawProductData": {
        "example": "{\"description\": \"pass data about the purchase\"}"
      },
      "productName": "Product Name",
      "quantity": 1
    }
  ],
  "token": "230377JSUM3F0275"
}
'
{"paymentId":"e416a462-33a3-4e80-ab8d-ffa2de666a2b"}
  1. With Coinflow Wallet, Coinflow manages the payer balance — no signed redemption is required from the merchant for the standard flow.

Advanced: Custom Redemption

Merchants who want full control over redemption can create and sign a redeem transaction themselves.

  1. Create a redeem transaction

    curl --request POST \
         --url https://api-sandbox.coinflow.cash/api/redeem/merchant \
         --header 'accept: application/json' \
         --header 'content-type: application/json' \
         --header 'x-coinflow-auth-blockchain: solana' \
         --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \
         --data '
    {
      "subtotal": {
        "cents": 500
      },
      "merchantId": "YOUR_MERCHANT_ID"
    }
    '
    {
      "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
    }
  2. Sign the transaction with the merchant wallet and submit it via Coinflow’s endpoint to settle the redemption.

    const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
    const bs58 = require('bs58');
    
    const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
    const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
    const privateKey = bs58.decode(privateKeyString);
    const keypair = Keypair.fromSecretKey(privateKey);
    const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3
    
    // return a signed tz
    async function signTransaction() {
      try {
        const decodedTransactionBytes = bs58.decode(base58Transaction);
        const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
        versionedTransaction.sign([keypair]); // wallet signs tx
        const serializedTransaction = versionedTransaction.serialize();
        const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58
    
        console.log(signed tx:', signedTransaction);
        return base58SignedTransaction; // This is what youll send to settle the redemption
    
      } catch (err) {
        console.error('Error signing the transaction:', err);
      }
    }
    
    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": "testtest",
      "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT"
    }
    '
  1. Add Chargeback protection on EVERY PAGE of your app
    • Note: This is required!