> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.coinflow.cash/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server.

# Credit Purchase Integration: USDC Settled Directly to a Solana Contract

> **Warning**
>
> **This page is for advanced / cryptocurrency-native companies.** If that's not you, head back to the [Quickstart](/guides/getting-started/quickstart) for the standard flows.

## Setup

> **Complete account setup first**
>
> This integration assumes you've completed the
> [Account Setup](/guides/getting-started/account-setup) prerequisites —
> sandbox merchant account, API key, team access, and any product-specific
> configuration (settlement location, chargeback protection, or wallet
> funding).

#### Developer Resources

**Quick Links:**

* [How does settlement to Solana Contract work](/guides/checkout/settlement-locations/settlement-to-contracts/settle-to-solana-contract/implement-settlement-to-solana-contract)
* [Testing Card Numbers to use on Sandbox](/guides/checkout/testing/testing-credit-cards)
* [Listening to checkout webhooks](/guides/developer-resources/webhooks/checkout-webhooks)
* [Customize the UI to match your company branding guidelines if using Coinflow's SDK or Checkout link](/guides/developer-resources/custom-branding)

**Authorization Headers:**

* `Authorization` — Your API key from the [merchant dashboard](https://sandbox-merchant.coinflow.cash/api-keys).
* `x-coinflow-auth-user-id` — A unique customer ID from your own systems identifying the payer or payee.
* `x-coinflow-auth-session-key` — A JWT that authorizes the payer. Valid for 24 hours; refresh after expiry.

## Checkout Link Implementation

1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\
   Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.

   **`SignUpEvent`**

   ```curl SignUpEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignUp",
     "customerId": "user-123-abc",
     "country": "US",
     "username": "therock72",
     "email": "dwaynejohnson@gmail.com",
     "firstName": "Dwayne",
     "lastName": "Johnson"
   }
   '
   ```

   **`SignInEvent`**

   ```curl SignInEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOU_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignIn",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```

   **`SignInFailureEvent`**

   ```curl SignInFailureEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignInFailure",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com",
     "failureReason": "Password Failed"
   }
   '
   ```

   **`BuyerChallengeEvent`**

   ```curl BuyerChallengeEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "BuyerChallenge",
     "type": "thirdPartyKyc",
     "status": "successfullyFulfilled",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```
2. [Get a checkout link](/api-reference/api-reference/checkout/get-checkout-link)\
   This endpoint will generate a link which you can embed in an iframe or redirect users directly to.

   **`Request`**

   ```curl Request
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/checkout/link \
   		--header 'Authorization: YOUR_API_KEY' \
        --header 'accept: application/json' \
        --header 'content-type: application/json' \
        --header 'x-coinflow-auth-blockchain: solana' \
        --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \
        --data '
   {
     "webhookInfo": {
       "example": "{\"depositId\": \"123-abc-456\"}"
     }, // Add any webhook info you want to receive here
     "subtotal": {
       "currency": "USD",
       "cents": 100
     },
     "settlementType": "Credits",
     "email": "user@gmail.com", // the purchasers email address
     "blockchain": "solana",
     "chargebackProtectionData": [
       {
         "productType": "", // Get this value from Coinflow after completing chargeback protection questionnaire
         "rawProductData": {
           "example": "{\"description\": \"something about the purchase\"}"
         }, // Pass as much descriptive data detailing the purchase.
         "productName": "Product Name",
         "quantity": 1
       }
     ],
     "deviceId": "123456789", // Get this from: /guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection
     "supportEmail": "support@mycompany.com"
    	}
   '
   ```

   **`Response`**

   ```json Response
   {"link":"https://sandbox.coinflow.cash/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. Submit a purchase through the provided link and go to the merchant dashboard to see the purchase record.
   > 📘 At this point, the purchase for credits is complete, and the payer has credits in their wallet.
   >
   > After the user has credits, they can use their credits for use at anytime.
4. [Create a redeem transaction](/api-reference/api-reference/redeem/get-redeem-transaction)

   **`Request`**

   ```curl Request
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/redeem \
        --header 'accept: application/json' \
        --header 'content-type: application/json' \
        --header 'x-coinflow-auth-blockchain: solana' \
        --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \
        --data '
   {
     "subtotal": {
       "currency": "USD",
       "cents": 100
     },
     "merchantId": "YOUR_MERCHANT_ID", // replace with your merchant id
     "transaction": "GLeC6hHyQoBUhGbVe6x6XHJKdXFeJauEqP8XfVpqz4eN16VZmFnDeHundU6JndUDpADijtuEycFhSzkr9wfBXacQwK6ZzEWM1RvddNKE4JTRgyV8zs5cLd37kT9yzc554F6Um293UDjEYJmygb21x3iSH5qszjdZvRvHZJ95bfkvU8MDWx9YAihG7BaC8JfK3YBvZ6uJD2damLJRRhy4XTDmsToMxnCsR6rKEtk2E88yTuPHXATzXyKeXUJZ6D53rBTF9yJy1rwNgHhXUn9kshU77dVt7TaS8orrBpujgAKpxnhMfjWi2rWGQhUvGLLYbn9ny42YxWXuXMKUstDt8wKCxNGH6u1Re7yspnpCbRXavvFSgzF7MveJvN7maA7q8cNw7Zq1x9nBFMQKp23Ra1VrXD1oziUC7JZVkU4HCw8eDsEKJy9udRofzopvnFzd1cqEseJF945YDAfAY4hjUcN5syZZg5EsSk1yBXa2nJaDhEwBn8zxQ8p7GEn5TVj8iVSYnfwr4534eSd1z1gunYdANtewVZFgUCRanXTTsNJucFu5HWTTYci2urT3G2fR3UmoNm5cK", // This should be a base58 encoded tx
     "chargebackProtectionData": [
       {
         "productType": "", //Get this from completing chargeback questionnaire
         "productName": "product name",
         "quantity": 1,
   			"rawProductData": {
           "example": "{\"description\": \"something about the purchase\"}"
         }, // Pass as much descriptive data detailing the purchase.
         "productName": "Product Name",
         "quantity": 1
       }
       }
     ]
   }
   '
   ```

   **`Response`**

   ```json Response
   {
     "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
   }
   ```
5. 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](/api-reference/api-reference/utilities/send-coinflow-transaction).

   **`Sign Transaction`**

   ```javascript Sign Transaction
   const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
   const bs58 = require('bs58');

   const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
   const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
   const privateKey = bs58.decode(privateKeyString);
   const keypair = Keypair.fromSecretKey(privateKey);
   const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3

   // return a signed tx
   async function signTransaction() {
     try {
       const decodedTransactionBytes = bs58.decode(base58Transaction);
       const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
       versionedTransaction.sign([keypair]); // wallet signs tx
       const serializedTransaction = versionedTransaction.serialize();
       const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58

       console.log(signed tx:', signedTransaction);
       return base58SignedTransaction; // This is what youll send to the blockchain

     } catch (err) {
       console.error('Error signing the transaction:', err);
     }
   }


   ```

   **`Send Transaction`**

   ```curl Send Transaction
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \
        --header 'accept: application/json' \
        --header 'content-type: application/json' \
        --data '
   {
     "merchantId": "testtest",
     "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT"
   }
   '
   ```

## React SDK Implementation

1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\
   Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.

   **`SignUpEvent`**

   ```curl SignUpEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignUp",
     "customerId": "user-123-abc",
     "country": "US",
     "username": "therock72",
     "email": "dwaynejohnson@gmail.com",
     "firstName": "Dwayne",
     "lastName": "Johnson"
   }
   '
   ```

   **`SignInEvent`**

   ```curl SignInEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOU_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignIn",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```

   **`SignInFailureEvent`**

   ```curl SignInFailureEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignInFailure",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com",
     "failureReason": "Password Failed"
   }
   '
   ```

   **`BuyerChallengeEvent`**

   ```curl BuyerChallengeEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "BuyerChallenge",
     "type": "thirdPartyKyc",
     "status": "successfullyFulfilled",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```
2. [Install Coinflow package](https://www.npmjs.com/package/@coinflowlabs/react-native)
   ```
   npm i @coinflowlabs/react-native
   ```
3. Below is an example of how to implement the `CoinflowPurchase` modal so a user can purchase credits with their payment method.

```javascript
<CoinflowPurchase
      wallet={{
        publicKey: new PublicKey('USER_PUBLIC_KEY'),
        signMessage: (message: UInt8Array) => Promise,
        sendTransaction: (transaction: Transaction | VersionedTransaction) => Promise
      }}
      connection={connection} // solana rpc connection
      blockchain={'solana'}
      merchantId={'testtest'} // Replace with your merchant id
      env={'sandbox || prod'}
      onSuccess={(...args) => {
        console.log('Purchase Success', args); // Provide your own function after payment success
      }}
      subtotal={{currency: Currency.USD,
                    cents: 100}} // purchase amount in USD
      webhookInfo={{
        productId: '123abc',
        item: 'sword',
      }} // Pass additional webhook info youd like to receive
      email="user@test.com" // payer's email address
      chargebackProtectionData={[
        {
          productName: "Product Name",
          productType: "gameOfSkill", // Get this value from Coinflow after filling out chargeback questionnaire
          quantity: 1,
          rawProductData: {
            productID: "sword12345",
            productDescription: "A legendary sword with magical powers.",
            productCategory: "Weapon",
            weight: "15 lbs",
            dimensions: "40 in x 5 in",
            origin: "Ancient Kingdom",
            craftedBy: "Master Blacksmith",
            craftingDate: "2024-06-19",
          }, // Customize with as much info you have on the purchase
        },
      ]}
      settlementType={SettlementType.Credits}
    />
```

3. Then, when the customer wants to redeem their credits, you can implement the `CoinflowPurchase` like below:
   ```javascript
   <CoinflowPurchase
         wallet={{
           publicKey: new PublicKey('USER_PUBLIC_KEY'),
           signMessage: (message: UInt8Array) => Promise,
           sendTransaction: (transaction: Transaction | VersionedTransaction) => Promise
         }}
         connection={connection} // solana rpc connection
         blockchain={'solana'}
         merchantId={'testtest'} // Replace with your merchant id
         env={'sandbox || prod'}
         onSuccess={(...args) => {
           console.log('Purchase Success', args); // Provide your own function after payment success
         }}
         subtotal={{currency: Currency.USD,
                       cents: 100}} // purchase amount in USD
         webhookInfo={{
           productId: '123abc',
           item: 'sword',
         }} // Pass additional webhook info youd like to receive
         email="user@test.com" // payer's email address
         chargebackProtectionData={[
           {
             productName: "Product Name",
             productType: "gameOfSkill", // Get this value from Coinflow after filling out chargeback questionnaire
             quantity: 1,
             rawProductData: {
               productID: "sword12345",
               productDescription: "A legendary sword with magical powers.",
               productCategory: "Weapon",
               weight: "15 lbs",
               dimensions: "40 in x 5 in",
               origin: "Ancient Kingdom",
               craftedBy: "Master Blacksmith",
               craftingDate: "2024-06-19",
             }, // Customize with as much info you have on the purchase
           },
         ]}
         settlementType={SettlementType.Credits}
   			transaction={tx} // This should be a base58 encoded tx created by the merchant.
         // 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.
       />
   ```
4. [Add Chargeback protection on EVERY PAGE of your app](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection)
   * Note: This is required!

## API Implementation

1. [Share payer events with Coinflow](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events)\
   Sharing major events that a payer makes throughout their lifecycle on your website prior to them making a purchase will allow us to collect more information about them and improve your approval rates.

   **`SignUpEvent`**

   ```curl SignUpEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignUp",
     "customerId": "user-123-abc",
     "country": "US",
     "username": "therock72",
     "email": "dwaynejohnson@gmail.com",
     "firstName": "Dwayne",
     "lastName": "Johnson"
   }
   '
   ```

   **`SignInEvent`**

   ```curl SignInEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOU_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignIn",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```

   **`SignInFailureEvent`**

   ```curl SignInFailureEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "SignInFailure",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com",
     "failureReason": "Password Failed"
   }
   '
   ```

   **`BuyerChallengeEvent`**

   ```curl BuyerChallengeEvent
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/events \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'content-type: application/json' \
        --data '
   {
     "eventType": "BuyerChallenge",
     "type": "thirdPartyKyc",
     "status": "successfullyFulfilled",
     "customerId": "user-123-abc",
     "country": "US",
     "email": "dwaynejohnson@gmail.com"
   }
   '
   ```
2. [Generate an API Key](https://sandbox-merchant.coinflow.cash/api-keys) from Merchant Dashboard > API Keys > Create.
3. [Get a Session Key](/api-reference/api-reference/authentication/get-session-key)\
   This creates a JWT for the payer and must be refreshed every 24 hours.

   **`Request`**

   ```curl Request
   curl --request GET \
        --url https://api-sandbox.coinflow.cash/api/auth/session-key \
        --header 'Authorization: YOUR_API_KEY' \
        --header 'accept: application/json' \
        --header 'x-coinflow-auth-blockchain: solana' \
        --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt'
   ```

   **`Response`**

   ```json Response
   {
     "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY"
   }
   ```

   **Note: Session keys are valid for 24 hours and must be refreshed upon expiration.**
4. [Get the Totals for the checkout](/api-reference/api-reference/checkout/get-totals)\
   This will return the total price inclusive of all fees for the purchase.

**`Request`**

```curl Request
curl --location 'https://api-sandbox.coinflow.cash/api/checkout/totals/YOUR_MERCHANT_ID' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--data '
{
  "subtotal": {
    "cents": 200
  }
}
'
```

**`Response`**

```json Response
//Response
{
    "card": {
        "subtotal": {
            "cents": 200
        },
        "creditCardFees": {
            "cents": 0
        },
        "chargebackProtectionFees": {
            "cents": 0
        },
        "gasFees": {
            "cents": 0
        },
        "total": {
            "cents": 200
        },
        "merchantPaidCreditCardFees": {
            "cents": 36
        },
        "merchantPaidGasFees": {
            "cents": 0
        },
        "merchantPaidChargebackProtectionFees": {
            "cents": 0
        }
    },
    "ach": {
        "subtotal": {
            "cents": 200
        },
        "creditCardFees": {
            "cents": 0
        },
        "chargebackProtectionFees": {
            "cents": 0
        },
        "gasFees": {
            "cents": 0
        },
        "total": {
            "cents": 200
        },
        "merchantPaidCreditCardFees": {
            "cents": 100
        },
        "merchantPaidGasFees": {
            "cents": 0
        },
        "merchantPaidChargebackProtectionFees": {
            "cents": 0
        }
    }
}
```

4. [Tokenize the Credit Card Number.](/recipes/recipes/pci-compliant-card-tokenization)  See tab: `Tokenize New Card`
5. [Enable a New Card Checkout](/api-reference/api-reference/checkout/card-checkout)\
   This endpoint will enable a new user who has never made a purchase to complete their purchase using the tokenized credit card retrieved from Step 4. Below is an example of how you'd call the card checkout endpoint:

**`Request`**

```curl Request
curl --location 'https://api-sandbox.coinflow.cash/api/checkout/card/testtest' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--data-raw '
{
  "subtotal": {
    "currency": "USD",
    "cents": 100
  },
  "webhookInfo": {
    "example": "{\"description\": \"whatever webhooks info you want to receive\"}"
  }, // pass whatever webhook info you want to receive
	"card": {
    "expYear": "29",
    "expMonth": "10",
    "email": "dwayne@therock.com",
    "firstName": "dwayne",
    "lastName": "johnson",
    "address1": "123 Rock Road",
    "city": "Chicago",
    "zip": "60606",
    "state": "IL",
    "country": "US",
    "cardToken": "230377JSUM3F0275" // Get this from: /recipes/recipes/pci-compliant-card-tokenization
  },
  "settlementType": "Credits",
  "authentication3DS": {
    "colorDepth": 30,
    "screenHeight": 1000,
    "screenWidth": 2000,
    "timeZone": 5
  }, // Get this from: /recipes/complete-checkout-with-3ds-challenge
  "chargebackProtectionData": [
    {
      "productType": "inGameProduct", // Get this after completing chargeback protection questionnaire
      "rawProductData": {
        "example": "{\"description\": \"pass data about the purchase\"}"
      },
      "productName": "Product Name",
      "quantity": 1
    }
  ]
}
'
```

**`Response`**

```json Response
{"paymentId":"bdc22a87-fb72-4f9d-a445-f26c04c8376c"}
```

5. [Re-tokenize a saved card number.](/recipes/recipes/pci-compliant-card-tokenization)  See tab: `Refresh Token w/ CVV`
6. [Enable a Saved Card Checkout](/api-reference/api-reference/checkout/token-checkout)\
   This endpoint will enable a returning user to complete a purchase with a previously saved card. The returning user will need to enter their CVV before confirming the purchase.\
   Once you've retrieved the refreshed card token, pass it into the [Saved Card Checkout endpoint](/api-reference/api-reference/checkout/token-checkout). Below is an example request:

```curl
curl --location 'https://api-sandbox.coinflow.cash/api/checkout/token/testtest' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiI5cnB2Mlc2cXlTaHdjd1RnWlhwaUZ1QzVrRkdZcHpoWXVnbXBLSzVMczRLdCIsImJsb2NrY2hhaW4iOiJzb2xhbmEiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3Mzc2NzA5MDgsImV4cCI6MTczNzc1NzMwOH0.muaqSAPV2jrezdUI4GGeP2srlRzb1ZvWcv9yAAZ6zpY' \
--header 'x-device-id: 123456789' \
--data '
{
  "settlementType": "Credits",
  "subtotal": {
    "currency": "USD",
    "cents": 100
  },
  "webhookInfo": {
    "example": "{\"description\": \"whatever webhooks info you want to receive\"}"
  },
  "authentication3DS": {
    "colorDepth": 30,
    "screenHeight": 1000,
    "screenWidth": 2000,
    "timeZone": 5
  },
  "chargebackProtectionData": [
    {
      "productType": "gameOfSkill",
      "rawProductData": {
        "example": "{\"description\": \"pass data about the purchase\"}"
      },
      "productName": "Product Name",
      "quantity": 1
    }
  ],
  "token": "230377JSUM3F0275"
}
'
```

```json
{"paymentId":"e416a462-33a3-4e80-ab8d-ffa2de666a2b"}
```

6. [Create a redeem transaction](/api-reference/api-reference/redeem/get-redeem-transaction)
   ```curl
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/redeem \
        --header 'accept: application/json' \
        --header 'content-type: application/json' \
        --header 'x-coinflow-auth-blockchain: solana' \
        --header 'x-coinflow-auth-wallet: 9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5Ls4Kt' \
        --data '
   {
     "subtotal": {
       "currency": "USD",
       "cents": 100
     },
     "merchantId": "YOUR_MERCHANT_ID", // replace with your merchant id
     "transaction": "GLeC6hHyQoBUhGbVe6x6XHJKdXFeJauEqP8XfVpqz4eN16VZmFnDeHundU6JndUDpADijtuEycFhSzkr9wfBXacQwK6ZzEWM1RvddNKE4JTRgyV8zs5cLd37kT9yzc554F6Um293UDjEYJmygb21x3iSH5qszjdZvRvHZJ95bfkvU8MDWx9YAihG7BaC8JfK3YBvZ6uJD2damLJRRhy4XTDmsToMxnCsR6rKEtk2E88yTuPHXATzXyKeXUJZ6D53rBTF9yJy1rwNgHhXUn9kshU77dVt7TaS8orrBpujgAKpxnhMfjWi2rWGQhUvGLLYbn9ny42YxWXuXMKUstDt8wKCxNGH6u1Re7yspnpCbRXavvFSgzF7MveJvN7maA7q8cNw7Zq1x9nBFMQKp23Ra1VrXD1oziUC7JZVkU4HCw8eDsEKJy9udRofzopvnFzd1cqEseJF945YDAfAY4hjUcN5syZZg5EsSk1yBXa2nJaDhEwBn8zxQ8p7GEn5TVj8iVSYnfwr4534eSd1z1gunYdANtewVZFgUCRanXTTsNJucFu5HWTTYci2urT3G2fR3UmoNm5cK", // This should be a base58 encoded tx
   }
   '
   ```
   ```json
   {
     "transaction": "5hAzkEBF2jNWz4Yo5mv63p2Nc8HKFyC4PhKmvtE5KbEdnssu5ihuBbYXnay6AysBCyiQBbo1rHkC7sqKn56zgoLmFDTAcK6f9UyX4cReT2c671UzhdG4Wa6jZh2BYCMu78nSesoeMSS9XQ6jXvRyA2fs1wRiMwRCaCEe8StVHmQVvwpof6Tv9WoTcQAAn4nYWqNMgBHLnpk5KAEj6QtBcub6fBW9hRsHDj6bW1XdhuokCVyoayg9KywYjva7cbPLJRZM9aNywUv41og9Jr1pvV6qqCcehXJ4kyFEuayAqhn1Zku4oFaoMrKe3uydjbpy2Pu1nv4wz4JQHa7yeaNWcQysKdEKsqi5dJSkGkaoRBKdM3nhCdTRLAvik4AZYSeBDP5unqd73aRekzX9Z7PmfzTC7FVTWLqtJA3Z3dze2QqHr7yLvgvZAhtPZgjXhW9U4YmLFsBwAfFy4T1GZUwBQirfmwYAhV9pBxnqLLHvfGTizmZLU22EGVrFAz6RDD4mogcUgxjFa56irwL3v5dd6BrpwZcwCDf35ad5AeeKx2JSJ5XmbKr7xmDATMFMqfGPu37mCwo8t6MUsdoqYFTAUhy6gvp4XKwouLMpQU4UnykXubFnUHkYZBkR9yurSExM835A6mtk1ufcVpYc1bc148ciM5w1ZPpC7W1M28u17jaECCnGSERfNettZNmkrQCK8rJ42bSqYa7dnnfnyFer7Exv8mFcFmFs4Br9k568wUHyUvQMrT4WTaY1EiQtc6WmWzHvmUxgc2ppNKRNXa7YFxQfNYbP4diA3s26cKymTqmGmuR8pEPoV5aabm8dmAtZhmVNuoF8S3M7WUVnMuWToFa8quKM4uVPgg4xWShnFdjv4MmsAbPpFcbfTeMDMfRXKAQLw2C6q2dgoJredwaG843HEgAjVmTN1H2Evnezc3cMXFuJUWdSwL22AEUsZJJwS6jNTLmGZBbgtPJVn3Wg4PGtJTky2uxWx3uL1B6AJxYEfh"
   }
   ```
7. 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](/api-reference/api-reference/utilities/send-coinflow-transaction).

   **`Sign Transaction`**

   ```javascript Sign Transaction
   const { Connection, Keypair, VersionedTransaction } = require('@solana/web3.js');
   const bs58 = require('bs58');

   const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
   const privateKeyString = 'YOUR_BASE58_PRIVATE_KEY';
   const privateKey = bs58.decode(privateKeyString);
   const keypair = Keypair.fromSecretKey(privateKey);
   const base58Transaction = 'REPLACE_WITH_REDEEM_TX'; //replace with tx returned from step 3

   // return a signed tz
   async function signTransaction() {
     try {
       const decodedTransactionBytes = bs58.decode(base58Transaction);
       const versionedTransaction = VersionedTransaction.deserialize(decodedTransactionBytes);
       versionedTransaction.sign([keypair]); // wallet signs tx
       const serializedTransaction = versionedTransaction.serialize();
       const base58SignedTransaction = bs58.encode(serializedTransaction); // encode signed tx to base58

       console.log(signed tx:', signedTransaction);
       return base58SignedTransaction; // This is what youll send to the blockchain

     } catch (err) {
       console.error('Error signing the transaction:', err);
     }
   }


   ```

   **`Send Transaction`**

   ```curl Send Transaction
   curl --request POST \
        --url https://api-sandbox.coinflow.cash/api/utils/send-coinflow-tx \
        --header 'accept: application/json' \
        --header 'content-type: application/json' \
        --data '
   {
     "merchantId": "testtest",
     "signedTransaction": "5gkDhvbf4ntXpmmN5pWqBRMLumB7z9En6tfgS19sdDZaXKzEMPRoP7DYZ1bMvqwS9xTQnw6AsR8ucnEtx35zqBryNmCKjWYGf1VW8WpeXYuqHhYHdWgEPxxXXY4iqNhexrodYWeyH2eXpAwNPFKo1wfLkVJsxARhdYu9o9HJU1Ba6x4ZZWmWoLFRL3yWZ2H1GytsubAmj7fzArjGuoSCUkHNzsSZpvAFux7Mstie5JuzvzGJqGc9tVTcUjrCmjkij8mdbN4rP3C6VFwyxDRt64DCJvc4A3epX8YhqW84wj7WXuxQVWcyjRHmyuaD4nhaHeyFMWYCjTo8ZywcoZJ3n7dvrzqQTXTSY2V2UmkApBE5Qkni2WiekTfjryQBKLUDFFAcHtZXE1gy1X4wCFgvbyi8USVAhqTH8Y86h62nhjVEcXqLxbwm48F7Fqq8QLtoBNg3j7BRLEdwXvjK7y6f7WF1iSnL2Q4b4fwVUwU37UZchBPKt1GcRw1pF2ohwZ9krK4dbfjUpa2w5HsrBgGfVttBaBUXaSvaxkJQmWwM1bfVtBHXJf8rCBt5uTDfvyPJjtzkZDE3irFQWXiJ2bA9HodZnz4myPM6AWFiCJXVcKjLsmTnYkUvQwZ84nzx7jvPp7ZXLeJ2fa5uMxdnHsSdjwoQeuaHPapDfCoawSSVoTtFMYPjREiaMqckCht7u2LLeedbdMvLsQt5btM8R9uCSFzYbpKQLZEwZ4XMmfxoqdTCagjoEe7Yg3o3XB7KqUJma6LwFJJwG24yprCEveYCrkD8GiqXmphmx2Q4M1Drk1ygKGDqLn246UWt9nxoZusqDSnzruHh7gaE8tgx1iH7z29Bkm6UAqDMLY3BnVgYJxuQkH4PcD2E2yrgrZDJuqQtMxyB2uFLe3eb75mnZjfshL4wYD54BScEmybHxjA2ee1T7ZUv8VJZ53c74wzZ8BdGM4NASnjtcVh5yWWWkURekMXPHFkrxytsoc4PjXwF7NaNaT"
   }
   '
   ```
8. [Add Chargeback protection on EVERY PAGE of your app](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection)
   * Note: This is required!