One-Time Purchase Integration: USDC Settlement to Solana Contract

Setup

Developer Resources

Quick Links:

Authorization Headers:

  • Authorization is your API Key. You can generate this from the merchant dashboard
  • x-coinflow-auth-user-id is a unique customer ID you use within your systems to identify the user withdrawing funds
  • x-coinflow-auth-blockchain should always be solana if your settlement location is the Coinflow in-app wallet
  • x-coinflow-auth-session-key is a JWT that authorizes the payer. This is valid for 24 hours and must be refreshed anytime after
  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.
    SignUpEvent
    1curl --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'
    SignInEvent
    1curl --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'
    SignInFailureEvent
    1curl --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'
    BuyerChallengeEvent
    1curl --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'
  2. Get a checkout link
    This endpoint will generate a link which you can embed in an iframe or redirect users directly to. Leverage the Checkout link to complete the payment. Once we receive the payment, Coinflow will send credits to the user’s wallet.
    Request
    1curl --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'
    Response
    1{"link":"https://sandbox.coinflow.cash/solana/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. Create a redeem transaction
    Create a redeem transaction instantly after the payer completes their card payment. The transaction passed should be a base58 encoded tx created by you and passed into our redeem endpoint. This transaction should be created as if the receiver (your whitelisted contract) will receive USDC as settlement.
Request
1curl --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'
Response
1{
2 "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
3}
  1. 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 Transaction
1const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
2const bs58 = require('bs58');
3
4const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
5const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
6const privateKey = bs58.decode(privateKeyString);
7const keypair = Keypair.fromSecretKey(privateKey);
8const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3
9
10// return a signed tx
11async 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 Transaction
1curl --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

  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.
    SignUpEvent
    1curl --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'
    SignInEvent
    1curl --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'
    SignInFailureEvent
    1curl --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'
    BuyerChallengeEvent
    1curl --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'
  2. Install Coinflow package
    npm i @coinflowlabs/react
  3. Below is an example of how to implement the 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 />
  1. Upon completion of the card payment, coinflow will send credits to the payer’s wallet. Then, subsequently call the redeem transaction upon success. To Create a redeem transaction- create and pass a base58 encoded tx created by you and passed into our redeem endpoint. This transaction should be created as if the receiver (your whitelisted contract) will receive USDC as settlement.

    Request
    1curl --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'
    Response
    1{
    2 "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
    3}
  2. 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 Transaction
    1const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
    2const bs58 = require('bs58');
    3
    4const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
    5const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
    6const privateKey = bs58.decode(privateKeyString);
    7const keypair = Keypair.fromSecretKey(privateKey);
    8const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3
    9
    10// return a signed tx
    11async 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 Transaction
    1curl --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'
  3. Add Chargeback protection on EVERY PAGE of your app

  • Note: This is required!

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.

    SignUpEvent
    1curl --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'
    SignInEvent
    1curl --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'
    SignInFailureEvent
    1curl --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'
    BuyerChallengeEvent
    1curl --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'
  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.

    Request
    1curl --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'
    Response
    1{
    2 "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY"
    3}

    Note: Session keys are valid for 30 minutes 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.

Request
1curl --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'
Response
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}
  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:
Request
1curl --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'
Response
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:
1curl --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. Create a redeem transaction

    1curl --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}
  2. 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 Transaction
    1const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
    2const bs58 = require('bs58');
    3
    4const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
    5const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
    6const privateKey = bs58.decode(privateKeyString);
    7const keypair = Keypair.fromSecretKey(privateKey);
    8const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3
    9
    10// return a signed tx
    11async 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 Transaction
    1curl --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'
  3. Add Chargeback protection on EVERY PAGE of your app

    • Note: This is required!