Card Checkout - Credits
Setup
Account Setup
You MUST complete the account setup section before you start integrating!
Developer Resources
- How does settlement to Solana Contract work
- Testing Card Numbers to use on Sandbox
- Listening to checkout webhooks
- Customize the UI to match your company branding guidelines if using Coinflow’s SDK or Checkout link
Authorization Headers
Authorizationis your API Key. You can generate this from the merchant dashboardx-coinflow-auth-user-idis a unique customer ID you use within your systems to identify the user withdrawing funds.x-coinflow-auth-blockchainshould always besolanaif your settlement location is the Coinflow in-app walletx-coinflow-auth-session-keyis a JWT that authorizes the payer. This is valid for 24 hours and must be refreshed anytime after.
Checkout Link Implementation
-
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.SignUpEvent1 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 ' SignInEvent1 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 ' SignInFailureEvent1 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 ' BuyerChallengeEvent1 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.Request1 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: https://docs.coinflow.cash/docs/implement-chargeback-protection#how-to-add-chargeback-protection 31 "supportEmail": "support@mycompany.com" 32 } 33 ' Response1 {"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.
-
Request
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 ' Response1 { 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.
Sign Transaction1 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 } Send Transaction1 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 '
React SDK Implementation
- 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.SignUpEvent1 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 ' SignInEvent1 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 ' SignInFailureEvent1 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 ' BuyerChallengeEvent1 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 ' - Install Coinflow package
npm i @coinflowlabs/react-native - Below is an example of how to implement the
CoinflowPurchasemodal 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 />
- Then, when the customer wants to redeem their credits, you can implement the
CoinflowPurchaselike 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 /> - Add Chargeback protection on EVERY PAGE of your app
- Note: This is required!
API Implementation
-
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.SignUpEvent1 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 ' SignInEvent1 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 ' SignInFailureEvent1 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 ' BuyerChallengeEvent1 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.Request1 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' Response1 { 2 "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY" 3 } Note: Session keys are valid for 30 minutes 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 the Credit Card Number. See tab:
Tokenize New Card - 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:
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: https://docs.coinflow.cash/recipes/pci-compliant-credit-card-tokenization 26 }, 27 "settlementType": "Credits", 28 "authentication3DS": { 29 "colorDepth": 30, 30 "screenHeight": 1000, 31 "screenWidth": 2000, 32 "timeZone": 5 33 }, // Get this from: https://docs.coinflow.cash/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"}
- Re-tokenize a saved card number. See tab:
Refresh Token w/ CVV - 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:
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 "chargebackProtectionData": [ 16 { 17 "productType": "gameOfSkill", //Get this from completing chargeback questionnaire 18 "productName": "product name", 19 "quantity": 1 20 } 21 ] 22 } 23 ' 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.
Sign Transaction1 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 } Send Transaction1 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
- Note: This is required!

