Credit Purchase Integration: USDC Settled Directly to a Solana Contract
Credit Purchase Integration: USDC Settled Directly to a Solana Contract
Credit Purchase Integration: USDC Settled Directly to a Solana Contract
This page is for advanced / cryptocurrency-native companies. If that’s not you, head back to the Quickstart for the standard flows.
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).
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.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.
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignUp", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "username": "therock72", 11 "email": "dwaynejohnson@gmail.com", 12 "firstName": "Dwayne", 13 "lastName": "Johnson" 14 } 15 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOU_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignIn", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com" 11 } 12 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignInFailure", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com", 11 "failureReason": "Password Failed" 12 } 13 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "BuyerChallenge", 8 "type": "thirdPartyKyc", 9 "status": "successfullyFulfilled", 10 "customerId": "user-123-abc", 11 "country": "US", 12 "email": "dwaynejohnson@gmail.com" 13 } 14 '
Get a checkout link
This endpoint will generate a link which you can embed in an iframe or redirect users directly to.
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/checkout/link \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'accept: application/json' \ 5 --header 'content-type: application/json' \ 6 --header 'x-coinflow-auth-blockchain: solana' \ 7 --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \ 8 --data ' 9 { 10 "webhookInfo": { 11 "example": "{\"depositId\": \"123-abc-456\"}" 12 }, // Add any webhook info you want to receive here 13 "subtotal": { 14 "currency": "USD", 15 "cents": 100 16 }, 17 "settlementType": "Credits", 18 "email": "user@gmail.com", // the purchasers email address 19 "blockchain": "solana", 20 "chargebackProtectionData": [ 21 { 22 "productType": "", // Get this value from Coinflow after completing chargeback protection questionnaire 23 "rawProductData": { 24 "example": "{\"description\": \"something about the purchase\"}" 25 }, // Pass as much descriptive data detailing the purchase. 26 "productName": "Product Name", 27 "quantity": 1 28 } 29 ], 30 "deviceId": "123456789", // Get this from: /guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection 31 "supportEmail": "support@mycompany.com" 32 } 33 '
1 {"link":"https://sandbox.coinflow.cash/solana/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"}
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.
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/redeem \ 3 --header 'accept: application/json' \ 4 --header 'content-type: application/json' \ 5 --header 'x-coinflow-auth-blockchain: solana' \ 6 --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \ 7 --data ' 8 { 9 "subtotal": { 10 "currency": "USD", 11 "cents": 100 12 }, 13 "merchantId": "YOUR_MERCHANT_ID", // replace with your merchant id 14 "transaction": "GLeC6hHyQoBUhGbVe6x6XHJKdXFeJauEqP8XfVpqz4eN16VZmFnDeHundU6JndUDpADijtuEycFhSzkr9wfBXacQwK6ZzEWM1RvddNKE4JTRgyV8zs5cLd37kT9yzc554F6Um293UDjEYJmygb21x3iSH5qszjdZvRvHZJ95bfkvU8MDWx9YAihG7BaC8JfK3YBvZ6uJD2damLJRRhy4XTDmsToMxnCsR6rKEtk2E88yTuPHXATzXyKeXUJZ6D53rBTF9yJy1rwNgHhXUn9kshU77dVt7TaS8orrBpujgAKpxnhMfjWi2rWGQhUvGLLYbn9ny42YxWXuXMKUstDt8wKCxNGH6u1Re7yspnpCbRXavvFSgzF7MveJvN7maA7q8cNw7Zq1x9nBFMQKp23Ra1VrXD1oziUC7JZVkU4HCw8eDsEKJy9udRofzopvnFzd1cqEseJF945YDAfAY4hjUcN5syZZg5EsSk1yBXa2nJaDhEwBn8zxQ8p7GEn5TVj8iVSYnfwr4534eSd1z1gunYdANtewVZFgUCRanXTTsNJucFu5HWTTYci2urT3G2fR3UmoNm5cK", // This should be a base58 encoded tx 15 "chargebackProtectionData": [ 16 { 17 "productType": "", //Get this from completing chargeback questionnaire 18 "productName": "product name", 19 "quantity": 1, 20 "rawProductData": { 21 "example": "{\"description\": \"something about the purchase\"}" 22 }, // Pass as much descriptive data detailing the purchase. 23 "productName": "Product Name", 24 "quantity": 1 25 } 26 } 27 ] 28 } 29 '
1 { 2 "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh" 3 }
Have the user wallet sign and send the transaction. Below is an example of how you can sign it. You may use Coinflow’s endpoint to then send the transaction to the solana blockchain.
1 const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js'); 2 const bs58 = require('bs58'); 3 4 const connection = new Connection('https://api.devnet.solana.com', 'confirmed'); 5 const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY'; 6 const privateKey = bs58.decode(privateKeyString); 7 const keypair = Keypair.fromSecretKey(privateKey); 8 const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3 9 10 // return a signed tx 11 async function signTransaction() { 12 try { 13 const decodedTransactionBytes = bs58.decode(base58Transaction); 14 const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes); 15 versionedTransaction.sign([keypair]); // wallet signs tx 16 const serializedTransaction = versionedTransaction.serialize(); 17 const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58 18 19 console.log(signed tx:', signedTransaction); 20 return base58SignedTransaction; // This is what youll send to the blockchain 21 22 } catch (err) { 23 console.error('Error signing the transaction:', err); 24 } 25 }
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \ 3 --header 'accept: application/json' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "merchantId": "testtest", 8 "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT" 9 } 10 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignUp", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "username": "therock72", 11 "email": "dwaynejohnson@gmail.com", 12 "firstName": "Dwayne", 13 "lastName": "Johnson" 14 } 15 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOU_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignIn", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com" 11 } 12 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignInFailure", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com", 11 "failureReason": "Password Failed" 12 } 13 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "BuyerChallenge", 8 "type": "thirdPartyKyc", 9 "status": "successfullyFulfilled", 10 "customerId": "user-123-abc", 11 "country": "US", 12 "email": "dwaynejohnson@gmail.com" 13 } 14 '
npm i @coinflowlabs/react-native
CoinflowPurchase modal so a user can purchase credits with their payment method.
1 <CoinflowPurchase 2 wallet={{ 3 publicKey: new PublicKey('USER_PUBLIC_KEY'), 4 signMessage: (message: UInt8Array) => Promise, 5 sendTransaction: (transaction: Transaction | VersionedTransaction) => Promise 6 }} 7 connection={connection} // solana rpc connection 8 blockchain={'solana'} 9 merchantId={'testtest'} // Replace with your merchant id 10 env={'sandbox || prod'} 11 onSuccess={(...args) => { 12 console.log('Purchase Success', args); // Provide your own function after payment success 13 }} 14 subtotal={{currency: Currency.USD, 15 cents: 100}} // purchase amount in USD 16 webhookInfo={{ 17 productId: '123abc', 18 item: 'sword', 19 }} // Pass additional webhook info youd like to receive 20 email="user@test.com" // payer's email address 21 chargebackProtectionData={[ 22 { 23 productName: "Product Name", 24 productType: "gameOfSkill", // Get this value from Coinflow after filling out chargeback questionnaire 25 quantity: 1, 26 rawProductData: { 27 productID: "sword12345", 28 productDescription: "A legendary sword with magical powers.", 29 productCategory: "Weapon", 30 weight: "15 lbs", 31 dimensions: "40 in x 5 in", 32 origin: "Ancient Kingdom", 33 craftedBy: "Master Blacksmith", 34 craftingDate: "2024-06-19", 35 }, // Customize with as much info you have on the purchase 36 }, 37 ]} 38 settlementType={SettlementType.Credits} 39 />
CoinflowPurchase like below:
1 <CoinflowPurchase 2 wallet={{ 3 publicKey: new PublicKey('USER_PUBLIC_KEY'), 4 signMessage: (message: UInt8Array) => Promise, 5 sendTransaction: (transaction: Transaction | VersionedTransaction) => Promise 6 }} 7 connection={connection} // solana rpc connection 8 blockchain={'solana'} 9 merchantId={'testtest'} // Replace with your merchant id 10 env={'sandbox || prod'} 11 onSuccess={(...args) => { 12 console.log('Purchase Success', args); // Provide your own function after payment success 13 }} 14 subtotal={{currency: Currency.USD, 15 cents: 100}} // purchase amount in USD 16 webhookInfo={{ 17 productId: '123abc', 18 item: 'sword', 19 }} // Pass additional webhook info youd like to receive 20 email="user@test.com" // payer's email address 21 chargebackProtectionData={[ 22 { 23 productName: "Product Name", 24 productType: "gameOfSkill", // Get this value from Coinflow after filling out chargeback questionnaire 25 quantity: 1, 26 rawProductData: { 27 productID: "sword12345", 28 productDescription: "A legendary sword with magical powers.", 29 productCategory: "Weapon", 30 weight: "15 lbs", 31 dimensions: "40 in x 5 in", 32 origin: "Ancient Kingdom", 33 craftedBy: "Master Blacksmith", 34 craftingDate: "2024-06-19", 35 }, // Customize with as much info you have on the purchase 36 }, 37 ]} 38 settlementType={SettlementType.Credits} 39 transaction={tx} // This should be a base58 encoded tx created by the merchant. 40 // Only pass a transaction when a customer wants to REDEEM their credits, after purchasing. DO NOT pass the tx when a customer is purchasing credits. 41 />
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.
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignUp", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "username": "therock72", 11 "email": "dwaynejohnson@gmail.com", 12 "firstName": "Dwayne", 13 "lastName": "Johnson" 14 } 15 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOU_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignIn", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com" 11 } 12 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "SignInFailure", 8 "customerId": "user-123-abc", 9 "country": "US", 10 "email": "dwaynejohnson@gmail.com", 11 "failureReason": "Password Failed" 12 } 13 '
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/events \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "eventType": "BuyerChallenge", 8 "type": "thirdPartyKyc", 9 "status": "successfullyFulfilled", 10 "customerId": "user-123-abc", 11 "country": "US", 12 "email": "dwaynejohnson@gmail.com" 13 } 14 '
Generate an API Key from Merchant Dashboard > API Keys > Create.
Get a Session Key
This creates a JWT for the payer and must be refreshed every 24 hours.
1 curl --request GET \ 2 --url https://api-sandbox.coinflow.cash/api/auth/session-key \ 3 --header 'Authorization: YOUR_API_KEY' \ 4 --header 'accept: application/json' \ 5 --header 'x-coinflow-auth-blockchain: solana' \ 6 --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt'
1 { 2 "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY" 3 }
Note: Session keys are valid for 24 hours and must be refreshed upon expiration.
Get the Totals for the checkout
This will return the total price inclusive of all fees for the purchase.
1 curl --location 'https://api-sandbox.coinflow.cash/api/checkout/totals/YOUR_MERCHANT_ID' \ 2 --header 'accept: application/json' \ 3 --header 'content-type: application/json' \ 4 --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \ 5 --data ' 6 { 7 "subtotal": { 8 "cents": 200 9 } 10 } 11 '
1 //Response 2 { 3 "card": { 4 "subtotal": { 5 "cents": 200 6 }, 7 "creditCardFees": { 8 "cents": 0 9 }, 10 "chargebackProtectionFees": { 11 "cents": 0 12 }, 13 "gasFees": { 14 "cents": 0 15 }, 16 "total": { 17 "cents": 200 18 }, 19 "merchantPaidCreditCardFees": { 20 "cents": 36 21 }, 22 "merchantPaidGasFees": { 23 "cents": 0 24 }, 25 "merchantPaidChargebackProtectionFees": { 26 "cents": 0 27 } 28 }, 29 "ach": { 30 "subtotal": { 31 "cents": 200 32 }, 33 "creditCardFees": { 34 "cents": 0 35 }, 36 "chargebackProtectionFees": { 37 "cents": 0 38 }, 39 "gasFees": { 40 "cents": 0 41 }, 42 "total": { 43 "cents": 200 44 }, 45 "merchantPaidCreditCardFees": { 46 "cents": 100 47 }, 48 "merchantPaidGasFees": { 49 "cents": 0 50 }, 51 "merchantPaidChargebackProtectionFees": { 52 "cents": 0 53 } 54 } 55 }
Tokenize New Card
1 curl --location 'https://api-sandbox.coinflow.cash/api/checkout/card/testtest' \ 2 --header 'accept: application/json' \ 3 --header 'content-type: application/json' \ 4 --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \ 5 --data-raw ' 6 { 7 "subtotal": { 8 "currency": "USD", 9 "cents": 100 10 }, 11 "webhookInfo": { 12 "example": "{\"description\": \"whatever webhooks info you want to receive\"}" 13 }, // pass whatever webhook info you want to receive 14 "card": { 15 "expYear": "29", 16 "expMonth": "10", 17 "email": "dwayne@therock.com", 18 "firstName": "dwayne", 19 "lastName": "johnson", 20 "address1": "123 Rock Road", 21 "city": "Chicago", 22 "zip": "60606", 23 "state": "IL", 24 "country": "US", 25 "cardToken": "230377JSUM3F0275" // Get this from: /recipes/recipes/pci-compliant-card-tokenization 26 }, 27 "settlementType": "Credits", 28 "authentication3DS": { 29 "colorDepth": 30, 30 "screenHeight": 1000, 31 "screenWidth": 2000, 32 "timeZone": 5 33 }, // Get this from: /recipes/complete-checkout-with-3ds-challenge 34 "chargebackProtectionData": [ 35 { 36 "productType": "inGameProduct", // Get this after completing chargeback protection questionnaire 37 "rawProductData": { 38 "example": "{\"description\": \"pass data about the purchase\"}" 39 }, 40 "productName": "Product Name", 41 "quantity": 1 42 } 43 ] 44 } 45 '
1 {"paymentId":"bdc22a87-fb72-4f9d-a445-f26c04c8376c"}
Refresh Token w/ CVV
1 curl --location 'https://api-sandbox.coinflow.cash/api/checkout/token/testtest' \ 2 --header 'accept: application/json' \ 3 --header 'content-type: application/json' \ 4 --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \ 5 --header 'x-device-id: 123456789' \ 6 --data ' 7 { 8 "settlementType": "Credits", 9 "subtotal": { 10 "currency": "USD", 11 "cents": 100 12 }, 13 "webhookInfo": { 14 "example": "{\"description\": \"whatever webhooks info you want to receive\"}" 15 }, 16 "authentication3DS": { 17 "colorDepth": 30, 18 "screenHeight": 1000, 19 "screenWidth": 2000, 20 "timeZone": 5 21 }, 22 "chargebackProtectionData": [ 23 { 24 "productType": "gameOfSkill", 25 "rawProductData": { 26 "example": "{\"description\": \"pass data about the purchase\"}" 27 }, 28 "productName": "Product Name", 29 "quantity": 1 30 } 31 ], 32 "token": "230377JSUM3F0275" 33 } 34 '
1 {"paymentId":"e416a462-33a3-4e80-ab8d-ffa2de666a2b"}
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/redeem \ 3 --header 'accept: application/json' \ 4 --header 'content-type: application/json' \ 5 --header 'x-coinflow-auth-blockchain: solana' \ 6 --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \ 7 --data ' 8 { 9 "subtotal": { 10 "currency": "USD", 11 "cents": 100 12 }, 13 "merchantId": "YOUR_MERCHANT_ID", // replace with your merchant id 14 "transaction": "GLeC6hHyQoBUhGbVe6x6XHJKdXFeJauEqP8XfVpqz4eN16VZmFnDeHundU6JndUDpADijtuEycFhSzkr9wfBXacQwK6ZzEWM1RvddNKE4JTRgyV8zs5cLd37kT9yzc554F6Um293UDjEYJmygb21x3iSH5qszjdZvRvHZJ95bfkvU8MDWx9YAihG7BaC8JfK3YBvZ6uJD2damLJRRhy4XTDmsToMxnCsR6rKEtk2E88yTuPHXATzXyKeXUJZ6D53rBTF9yJy1rwNgHhXUn9kshU77dVt7TaS8orrBpujgAKpxnhMfjWi2rWGQhUvGLLYbn9ny42YxWXuXMKUstDt8wKCxNGH6u1Re7yspnpCbRXavvFSgzF7MveJvN7maA7q8cNw7Zq1x9nBFMQKp23Ra1VrXD1oziUC7JZVkU4HCw8eDsEKJy9udRofzopvnFzd1cqEseJF945YDAfAY4hjUcN5syZZg5EsSk1yBXa2nJaDhEwBn8zxQ8p7GEn5TVj8iVSYnfwr4534eSd1z1gunYdANtewVZFgUCRanXTTsNJucFu5HWTTYci2urT3G2fR3UmoNm5cK", // This should be a base58 encoded tx 15 } 16 '
1 { 2 "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh" 3 }
Have the user wallet sign and send the transaction. Below is an example of how you can sign it. You may use Coinflow’s endpoint to then send the transaction to the solana blockchain.
1 const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js'); 2 const bs58 = require('bs58'); 3 4 const connection = new Connection('https://api.devnet.solana.com', 'confirmed'); 5 const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY'; 6 const privateKey = bs58.decode(privateKeyString); 7 const keypair = Keypair.fromSecretKey(privateKey); 8 const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3 9 10 // return a signed tz 11 async function signTransaction() { 12 try { 13 const decodedTransactionBytes = bs58.decode(base58Transaction); 14 const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes); 15 versionedTransaction.sign([keypair]); // wallet signs tx 16 const serializedTransaction = versionedTransaction.serialize(); 17 const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58 18 19 console.log(signed tx:', signedTransaction); 20 return base58SignedTransaction; // This is what youll send to the blockchain 21 22 } catch (err) { 23 console.error('Error signing the transaction:', err); 24 } 25 }
1 curl --request POST \ 2 --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \ 3 --header 'accept: application/json' \ 4 --header 'content-type: application/json' \ 5 --data ' 6 { 7 "merchantId": "testtest", 8 "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT" 9 } 10 '
Add Chargeback protection on EVERY PAGE of your app
