> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.coinflow.cash/guides/checkout/implementation-overview/implementation-guides/advanced-use-cases/credit-purchase-usdc-to-coinflow-wallet/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server. # Credit Purchases — Settle to Coinflow Wallet ## Setup > **Complete account setup first** > > This integration assumes you've completed the > [Account Setup](/guides/getting-started/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:** * [How does settlement to Coinflow Wallet work](/guides/checkout/settlement-locations/settlement-to-coinflow-wallet) * [Testing Card Numbers to use on Sandbox](/guides/checkout/testing/testing-credit-cards) * [Listening to checkout webhooks](/guides/developer-resources/webhooks/checkout-webhooks) * [Customize the UI to match your company branding guidelines if using Coinflow's SDK or Checkout link](/guides/developer-resources/custom-branding) **Authorization Headers:** * `Authorization` — Your API key from the [merchant dashboard](https://sandbox-merchant.coinflow.cash/api-keys). * `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. ## Checkout Link Implementation 1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\ 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. **`SignUpEvent`** ```curl SignUpEvent 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" } ' ``` **`SignInEvent`** ```curl SignInEvent 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" } ' ``` **`SignInFailureEvent`** ```curl SignInFailureEvent 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" } ' ``` **`BuyerChallengeEvent`** ```curl BuyerChallengeEvent 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](/api-reference/api-reference/checkout/get-checkout-link)\ This endpoint will generate a link which you can embed in an iframe or redirect users directly to. **`Request`** ```curl 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-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" } ' ``` **`Response`** ```json Response {"link":"https://sandbox.coinflow.cash/purchase-v2/testtest?sessionKey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzE5MDQsImV4cCI6MTczNzc1ODMwNH0.zpCD3yH6eeEQHfDHzj2lLeD4-irLz61bgcwcp0gTi_Y¢s=100¤cy=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](/api-reference/api-reference/redeem/get-merchant-wallet-redeem-transaction). **`Request`** ```curl Request 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" } ' ``` **`Response`** ```json Response { "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh" } ``` 2. Sign the transaction with the merchant wallet and submit it via Coinflow's endpoint to [settle the redemption](/api-reference/api-reference/utilities/send-coinflow-transaction). **`Sign Transaction`** ```javascript Sign Transaction 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); } } ``` **`Send Transaction`** ```curl 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": "testtest", "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT" } ' ``` ## React SDK Implementation 1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\ 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. **`SignUpEvent`** ```curl SignUpEvent 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" } ' ``` **`SignInEvent`** ```curl SignInEvent 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" } ' ``` **`SignInFailureEvent`** ```curl SignInFailureEvent 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" } ' ``` **`BuyerChallengeEvent`** ```curl BuyerChallengeEvent 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](https://www.npmjs.com/package/@coinflowlabs/react) ``` 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. ```jsx import {CoinflowPurchase} from '@coinflowlabs/react'; { 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](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection) — 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](#advanced-custom-redemption) below in the API section for the redemption-transaction creation flow. ## API Implementation 1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\ 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. **`SignUpEvent`** ```curl SignUpEvent 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" } ' ``` **`SignInEvent`** ```curl SignInEvent 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" } ' ``` **`SignInFailureEvent`** ```curl SignInFailureEvent 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" } ' ``` **`BuyerChallengeEvent`** ```curl BuyerChallengeEvent 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](https://sandbox-merchant.coinflow.cash/api-keys) from Merchant Dashboard > API Keys > Create. 3. [Get a Session Key](/api-reference/api-reference/authentication/get-session-key)\ This creates a JWT for the payer and must be refreshed every 24 hours. **`Request`** ```curl 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-user-id: user-123-abc' ``` **`Response`** ```json Response { "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](/api-reference/api-reference/checkout/get-totals)\ This will return the total price inclusive of all fees for the purchase. **`Request`** ```curl Request 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`** ```json Response //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 } } } ``` 4. [Tokenize the Credit Card Number.](/recipes/recipes/pci-compliant-card-tokenization) See tab: `Tokenize New Card` 5. [Enable a New Card Checkout](/api-reference/api-reference/checkout/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: **`Request`** ```curl Request 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 } ] } ' ``` **`Response`** ```json Response {"paymentId":"bdc22a87-fb72-4f9d-a445-f26c04c8376c"} ``` 5. [Re-tokenize a saved card number.](/recipes/recipes/pci-compliant-card-tokenization) See tab: `Refresh Token w/ CVV` 6. [Enable a Saved Card Checkout](/api-reference/api-reference/checkout/token-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](/api-reference/api-reference/checkout/token-checkout). Below is an example request: ```curl 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" } ' ``` ```json {"paymentId":"e416a462-33a3-4e80-ab8d-ffa2de666a2b"} ``` 6. 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](/api-reference/api-reference/redeem/get-merchant-wallet-redeem-transaction) ```curl 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" } ' ``` ```json { "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh" } ``` 2. Sign the transaction with the merchant wallet and submit it via Coinflow's endpoint to [settle the redemption](/api-reference/api-reference/utilities/send-coinflow-transaction). **`Sign Transaction`** ```javascript Sign Transaction 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); } } ``` **`Send Transaction`** ```curl 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": "testtest", "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT" } ' ``` 7) [Add Chargeback protection on EVERY PAGE of your app](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection) * Note: This is required!