For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
RegisterLoginSandbox Login
GuidesRecipesAPI Reference
GuidesRecipesAPI Reference
  • Getting Started
    • Getting Started with Checkout
    • ACH Checkout
    • Card Checkout with Credits
    • Card Checkout
    • Direct USDC Settlement
    • Fiat/Crypto Pay-ins
    • Secure Marketplace Checkout
    • EVM Checkout
    • How to Enable Checkout with Credit Cards
    • Quick Start Marketplace Implementation
    • Payouts
    • Common FAQs
  • Checkout
      • Getting Started with Implmentation
        • Credit Purchase - USDC to BYO Wallet (EVM)
        • Credit Purchase - USDC to Coinflow/BYO Wallet (Solana)
        • Credit Purchase - USDC to Coinflow Wallet
        • Credit Purchase - USDC to Solana Contract
        • Credit Purchase - USDC to EVM Contract
        • One-Time Purchase - USDC to Coinflow/BYO Wallet
        • One-Time Purchase - USDC to EVM Contract
        • One-Time Purchase - USDC to Solana Contract
        • One-Time Purchase - USDC to 3rd Party
        • One-Time Purchase - USDC to Stellar Contract
        • One-Time Purchase - Direct USDC Transfer (Stellar)
      • Mobile App Payments
    • Settlement Locations
    • Checkout Webhooks
  • Payouts
    • Payout Overview
    • What is a Payout
  • Subscriptions
    • Subscriptions Overview
  • Marketplaces
    • Marketplace Overview
    • How Marketplaces Work
    • How to Withdraw USDC
    • Countries Eligible for USDC Withdraw
    • Marketplaces Webhooks
    • Marketplaces Implementation
  • Developer Resources
    • Custom Branding
    • Checkout Implementation
    • Webhooks
  • Merchant Dashboard
    • Login & Account Access
    • Users and Roles
    • Rate Limits
    • Developer Contact
LogoLogo
RegisterLoginSandbox Login
On this page
  • Summary
  • Setup
  • Checkout Implementation
  • React SDK
  • API Implementation
  • Adding 3DS to Card Checkout
  • Adding Chargeback Protection
CheckoutImplementation OverviewImplementation Guides

Credit Purchase Integration: USDC Settled Directly to EVM Contract

Was this page helpful?
Previous

One-Time Purchase Integration - USDC Settlement

Accept credit card payments and receive USDC in your Coinflow wallet or BYO wallet
Next
Built with

Summary

This implementation guide outlines how Merchants on EVM chains can accept pay-ins and settle to a contract.

Setup

Account Setup

You MUST complete the account setup section before you start integrating!

1Register a sandbox merchant account or Login to your sandbox merchant account
2Create sandbox API Key
3Add Team Members to your sandbox account
4Add chargeback protection script to every page of your app
5

Configure settlement settings - Select where to receive revenue:

  • Your Own Merchant Wallet
Developer Resources

Quick Links:

  • 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:

  • 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

Checkout Implementation

React SDK

  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
  1. Tokenize the checkout parameters. This encrypts the checkout parameters so bad actors cannot tamper with the checkout args.
Request
1curl --location 'https://api-sandbox.coinflow.cash/api/checkout/jwt-token' \
2--header 'Authorization: YOUR_API_KEY' \
3--header 'accept: application/json' \
4--header 'content-type: application/json' \
5--data-raw '
6{
7 "webhookInfo": {
8 "example": "{\"nftId\":\"123abc\"}"
9 },
10 "subtotal": {
11 "currency": "USD",
12 "cents": 100
13 },
14 "transactionData": {
15 "transaction": {
16 "data": "0x...", // Function call data of the transaction
17 "to": "0x..." // Your Whitelisted Contract address
18 }
19 },
20 "email": "payer@gmail.com",
21 "blockchain": "base",
22 "chargebackProtectionData": [
23 {
24 "productName": "My Product",
25 "quantity": 1,
26 "rawProductData": {
27 "example": "{\"description\":\"description of nft\"}"
28 },
29 "productType": "inGameProduct" // This will change on prod
30 }
31 ],
32 "deviceId": "123456789"
33 "settlementType": "Credits"
34}
35'
Response
{
"checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguCjgOKYgueAleiAnN2j5IGM4LGn46CD5oOb4LCF44CQ7Iqy4YCF6KSz4KCI7KaczLDGkOuhgNqE44iA7rWwybDgp6DHgOCumeawgOSQqeSio0LgsJ3njaPmoYXItOa1ku6AjOyFieKmlOiTke67iOWCguWxiOmroOSNuO65suOou-mUremsreWZqOSytueBrOeBpOGgqOSZiOaxrOKhiOiRpOmitOGxiOG7vuuYnOeDmOeBjOChhuCglOuTiOunuOyYlOawmOqXtuujvuSyuuuSnOy7mOqglOSZqOahpOeVrOiwmOShsOKglOaphuGhjOuXjeiRhuaStOSZjFx1ZGQxY-K7k-uQlFx1ZDg2NO-kqOmUq-qHg-6Xqu-pmuySoeGxhuSVhueDquqYiOmHlOShmuGzmOKgnOaikeSuuFx1ZGExOOebvuKisuuguOiSqdOD4LCy4Y6B7IqZ5LO045Cb6qeM4o2D6Iyc7KOR4ZKt4ZyC6I2h6oCy44SMzZPSheyHmeixmOOyhsyE5IWC7oCo5LCO46uJ0rfvg6Dos6jMmOWqguiMi-qSjOu4nOqdkuivsuerpeWljOGmlemCi-6ZmeyFsOuItOCouuKDpeqCoeuAnOiImeGciuyNqeaIiuSxseWkrtek64S4XHVkODRi4YiN6LqnwqDngLjojJrhnIzsrYLpm43rqI3jjKbotoztmJjigYLlkoTihILoloXpi5HtkafijJHolZTogYLosoHnlZvmmonohYDnhbHooLTrjIXcr-mWou2GsOSwsuGchOm6g-qrmOGBmeieoOyfoemhiOWBsOGSqeWohOyzkO6rm-yhmeOQrOaAq-STqeGnpuSxteCoquWSgO6JkuqwnuGBmtys6Yax4rGQ5JS46rSH6ICF74iAIiwibWVyY2hhbnRJZCI6InRlc3R0ZXN0IiwiaWRlbXBvdGVuY3lLZXkiOiJJSzVlZWE3YzI3LWEyMjgtNDcyMC1iYTVkLWI1ZDA0ZDUzMzA3MCIsInN1YnRvdGFsIjp7ImN1cnJlbmN5IjoiVVNEIiwiY2VudHMiOjUwMH0sImlhdCI6MTc0Mjg1NTY3OCwiZXhwIjoxNzQyOTQyMDc4fQ.2dGfWnazfyHaz_uEWKM9RU-jh-tXUSMPFZJdNvmMPwo"
}
  1. Implement CoinflowPurchase component
1<CoinflowPurchase
2 wallet={{
3 address: string;
4 sendTransaction: (transaction) => Promise<{hash: string}>; // This isn't technically needed as the end user's wallet is never sending a transaction
5 signMessage: (message: string) => Promise;
6 }}
7 merchantId={'YOUR_MERCHANT_ID'} // Replace with your merchant ID
8 env={'sandbox || prod'}
9 onSuccess={(...args) => console.log('Purchase Success', args)}
10 blockchain={'base'}
11 subtotal={{cents: 100, currency: Currency.USD}} // Purchase amount in usdc
12jwtToken = {'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguCjgOKYgueAleiAnN2j5IGM4LGn46CD5oOb4LCF44CQ7Iqy4YCF6KSz4KCI7KaczLDGkOuhgNqE44iA7rWwybDgp6DHgOCumeawgOSQqeSio0LgsJ3njaPmoYXItOa1ku6AjOyFieKmlOiTke67iOWCguWxiOmroOSNuO65suOou-mUremsreWZqOSytueBrOeBpOGgqOSZiOaxrOKhiOiRpOmitOGxiOG7vuuYnOeDmOeBjOChhuCglOuTiOunuOyYlOawmOqXtuujvuSyuuuSnOy7mOqglOSZqOahpOeVrOiwmOShsOKglOaphuGhjOuXjeiRhuaStOSZjFx1ZGQxY-K7k-uQlFx1ZDg2NO-kqOmUq-qHg-6Xqu-pmuySoeGxhuSVhueDquqYiOmHlOShmuGzmOKgnOaikeSuuFx1ZGExOOebvuKisuuguOiSqdOD4LCy4Y6B7IqZ5LO045Cb6qeM4o2D6Iyc7KOR4ZKt4ZyC6I2h6oCy44SMzZPSheyHmeixmOOyhsyE5IWC7oCo5LCO46uJ0rfvg6Dos6jMmOWqguiMi-qSjOu4nOqdkuivsuerpeWljOGmlemCi-6ZmeyFsOuItOCouuKDpeqCoeuAnOiImeGciuyNqeaIiuSxseWkrtek64S4XHVkODRi4YiN6LqnwqDngLjojJrhnIzsrYLpm43rqI3jjKbotoztmJjigYLlkoTihILoloXpi5HtkafijJHolZTogYLosoHnlZvmmonohYDnhbHooLTrjIXcr-mWou2GsOSwsuGchOm6g-qrmOGBmeieoOyfoemhiOWBsOGSqeWohOyzkO6rm-yhmeOQrOaAq-STqeGnpuSxteCoquWSgO6JkuqwnuGBmtys6Yax4rGQ5JS46rSH6ICF74iAIiwibWVyY2hhbnRJZCI6InRlc3R0ZXN0IiwiaWRlbXBvdGVuY3lLZXkiOiJJSzVlZWE3YzI3LWEyMjgtNDcyMC1iYTVkLWI1ZDA0ZDUzMzA3MCIsInN1YnRvdGFsIjp7ImN1cnJlbmN5IjoiVVNEIiwiY2VudHMiOjUwMH0sImlhdCI6MTc0Mjg1NTY3OCwiZXhwIjoxNzQyOTQyMDc4fQ.2dGfWnazfyHaz_uEWKM9RU-jh-tXUSMPFZJdNvmMPwo'}
13/>
  1. Customize the UI on your dashboard
  2. Whitelist your url By whitelisting your domain, checkout can only be completed on your domain. This protects against bad actors trying to take your checkout link and injecting it onto their site.

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. Fetch a session key This creates a JWT token for the customer, and authorizes the user to call these endpoints. You will pass the returned session key as x-coinflow-auth-session-key header.
    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: base' \
    6 --header 'x-coinflow-auth-wallet: 0xd11cc1D037B49098130BDeB592d468E3fe131240'
    Response
    {
    "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y"
    }
  3. Get the Totals for the checkout to show the customer a quote inclusive of all fees.
    Request
    1curl --request POST \
    2 --url https://api-sandbox.coinflow.cash/api/checkout/totals/merchantId \
    3 --header 'accept: application/json' \
    4 --header 'content-type: application/json' \
    5 --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y' \
    6 --data '
    7{
    8 "subtotal": {
    9 "cents": 100
    10 },
    11 "settlementType": "USDC"
    12}
    13'
    Response
    {
    "card": {
    "subtotal": {
    "cents": 100
    },
    "creditCardFees": {
    "cents": 40
    },
    "chargebackProtectionFees": {
    "cents": 0
    },
    "gasFees": {
    "cents": 0
    },
    "total": {
    "cents": 140
    }
    },
    "ach": {
    "subtotal": {
    "cents": 100
    },
    "creditCardFees": {
    "cents": 100
    },
    "chargebackProtectionFees": {
    "cents": 0
    },
    "gasFees": {
    "cents": 0
    },
    "total": {
    "cents": 200
    }
    }
    }
  4. Tokenize the Credit Card Number. See tab: Tokenize New Card
  5. Tokenize the checkout parameters. This encrypts the checkout parameters so bad actors cannot tamper with the checkout args.
    Request
    1curl --request POST \
    2 --url https://api-sandbox.coinflow.cash/api/checkout/jwt-token \
    3 --header 'Authorization: YOUR_API_KEY' \
    4 --header 'accept: application/json' \
    5 --header 'content-type: application/json' \
    6 --data '
    7{
    8 "subtotal": {
    9 "currency": "USD",
    10 "cents": 500
    11 },
    12 "blockchain": "base",
    13 "settlementType": "Credits"
    14}
    15'
    Response
    {
    "checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXgsOA4piA54Sg4rGw4pyB5LWb6IyY4KOA4aaGxrHhgLvUheaAq9ia7YGp6qGQ4YaR54KA4LSI5aCH5p6A4Y6A5LyA4LiA5bKwxLDIoOGDgueymOKAg-OKrumbg-GshNWR4pqQ5KSC4rCU6K2N5amN6qq0XHVkYjJk64at45K54pOY6KGy5p6U65Oa4bGl4oKg7Y6F4p2Q64uC4pSl6oGA6piL5IGF5Y-B6LqS7J6T6IeD6IOg6o-D6pqQ44OD6Jmg6LSg5ouD4pSw4puI6KCg7YKi5JCg7ImH6o2l6pi15ZCL5pqX6YuB5IOF5Z6X6ZqV5Jaj6J6T6ruK5oGE4bml7Zeo5ISA17JcdTAwMDAiLCJtZXJjaGFudElkIjoibWVsbG8iLCJpZGVtcG90ZW5jeUtleSI6IklLMDFhMjFlMjYtM2M4YS00YTk0LTgyNmEtNmNiY2JiYjMyZGMzIiwic3VidG90YWwiOnsiY3VycmVuY3kiOiJVU0QiLCJjZW50cyI6MjAwfSwiaWF0IjoxNzUyNjE3MTkzLCJleHAiOjE3NTI2MTg5OTN9.iwplS7JwI2OVDFHyKk-9CsgNDA6cE-W7ScSclktCvzw"
    }
  6. Enable a New Card Checkout This endpoint will enable a new user who has never made a purchase to complete their purchase with a credit card. 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 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36' \
      5--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpYXQiOjE3NDYxNDU4MTEsImV4cCI6MTc0NjIzMjIxMX0.uJsjBHVnQ8wg5jSjqJUh8mz6IAqcy9lZuIknZCgINNo' \
      6--header 'x-coinflow-client-ip: 64.227.3.71' \
      7--header 'x-device-id: 123456789' \
      8--data-raw '
      9{
      10 "subtotal": {
      11 "currency": "USD",
      12 "cents": 500
      13 },
      14 "card": {
      15 "cardToken": "411111YJM5TX1111",
      16 "expYear": "30",
      17 "expMonth": "10",
      18 "email": "iamapayer@gmail.com",
      19 "firstName": "Dwayne",
      20 "lastName": "Johnson",
      21 "address1": "380 Prospect Ave",
      22 "city": "Brooklyn",
      23 "zip": "11215",
      24 "state": "NY",
      25 "country": "US"
      26 },
      27 "jwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXgsOA4piA54Sg4rGw4pyB5LWb6IyY4KOA4aaGxrHhgLvUheaAq9ia7YGp6qGQ4YaR54KA4LSI5aCH5p6A4Y6A5LyA4LiA5bKwxLDIoOGDgueymOKAg-OKrumbg-GshNWR4pqQ5KSC4rCU6K2N5amN6qq0XHVkYjJk64at45K54pOY6KGy5p6U65Oa4bGl4oKg7Y6F4p2Q64uC4pSl6oGA6piL5IGF5Y-B6LqS7J6T6IeD6IOg6o-D6pqQ44OD6Jmg6LSg5ouD4pSw4puI6KCg7YKi5JCg7ImH6o2l6pi15ZCL5pqX6YuB5IOF5Z6X6ZqV5Jaj6J6T6ruK5oGE4bml7Zeo5ISA17JcdTAwMDAiLCJtZXJjaGFudElkIjoibWVsbG8iLCJpZGVtcG90ZW5jeUtleSI6IklLMDFhMjFlMjYtM2M4YS00YTk0LTgyNmEtNmNiY2JiYjMyZGMzIiwic3VidG90YWwiOnsiY3VycmVuY3kiOiJVU0QiLCJjZW50cyI6MjAwfSwiaWF0IjoxNzUyNjE3MTkzLCJleHAiOjE3NTI2MTg5OTN9.iwplS7JwI2OVDFHyKk-9CsgNDA6cE-W7ScSclktCvzw"
      28}
      29'
      Response
      {
      "paymentId": "f3fc8a34-680b-4b91-905b-1db5628bbb0e"
      }
  7. Re-tokenize a saved card number. See tab: Refresh Token w/ CVV
  8. 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:
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 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36' \
5--header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y' \
6--header 'x-coinflow-client-ip: 64.227.3.71' \
7--header 'x-device-id: 123456789' \
8--data '
9{
10 "subtotal": {
11 "currency": "USD",
12 "cents": 500
13 },
14 "jwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXgsmg4LiC44Cg6bCF5pWB6LCE7ICz55CX5ICW0ITjgIjsvLjUsOG2j-aLtOuypO6ngeGAgeqEhuiDrOuAgueAie6AgeyAi-i0uETsrovijIQ24aiU6YaR6qq46JSA7LC67Kej7K6C66i246G15YWE6qyc4rGY6ZSp46qH5bC84KaJXHVkYmE45JqZ55uoM1x1ZDg1MO6Lme2MkO6loOKBkOWPu-GKoO6Bo-qDkO6kouGHkOKDqeSomeOAoeqEouqToOWGk--jq-qDqOOvo-GHgO6OhuKMueKmoemZo-SemO2IseaBm-GHkeaBkeaHoOSUq-qHleWUoeyKueifu--kq-GEoO6EqemFouSyueWvpOOIkOWEkOuttO6FouqHoOWBle6UkOWMkeSzk-y3kuqHkOWKolx1ZGUxOeyFneuIhe6Bl-qNjO2Fo-GYkeaHkO6vue6HreuRjOOwv-i5r-6GouqGoueRlOmKn-y6g-eOkOuAkO2InuiTgeaHge2DqOylosuW7ISN3ZnvkYjgooLhqq3qnoXtg4jksKjlmKLhqabqh4zpkazlvJ7pg4DgqYDjlLHtkLzhmKfknoLkg5zqi77mkJfooqroiaLqgJzpkr7lqoLonIPtiqjgsZ3ihpRcdWRmYzbkmKXigabuoLrhjKnkpbLlgr3suIjnurHgoaXkgYPgq7rmtafil4HgpbHsg5DpibvnobnguafrhInuro3ngbbPguGOo-qLhOG4iOG8neC4huSMoeWzpuS8jem_geCuhOqdtOekoO2Sn-2Jp-2Pg-KNhlx1ZDgwY-CmjuCoi-ickO6YjuqmkeGng-aThualkOShlOOukOG9oOimkOyqpOiDs-ykg-SHmuiMse-5lOKUgOKcgOGUoO6zmOqrkeW0h-aes-GXisaz5ruL4Kap2LDsq7_mkJ3pjK_vkpron6XlmLjlsJvksavrmJjso4jeieWuv-OQn-Syj-63vMuBXHVkOGU57IaU5biY76WD3Yrki6jjp6XgoJzjppfmuoztnoruqovsjJvusL3jgavri6jrmKnqrIvhgo7Ng-SLhOWEm-66oOOCjuKUpOaPmO6Ct-SMsOuzsuu9puWLvuGgpuqKk-mQoeC6g-WhhO-4h-K4iO6Cjeq0k-qqkuisnuSEkOSIv-KBjeqCguaotOK-o-ywn-C4quOItuiWtuq8ieuDoeGJhOunpuGGu-itheu6seOVruiDlOqgmuqYhuezvuG5oeavkOaoleyKkeaJuOChi-OMhNCT27vvq6LqmojmgKnroYzklJHikpHijqXljoLloLrguoLlgovhqqnqh4rvqbvmvpHupKBcdTAwMGLukIAiLCJtZXJjaGFudElkIjoidGVzdHRlc3QiLCJpZGVtcG90ZW5jeUtleSI6IklLODZjMDdkM2MtMWRmZi00YTY1LTg0YWYtYThjNTkxNmQyYTZiIiwic3VidG90YWwiOnsiY3VycmVuY3kiOiJVU0QiLCJjZW50cyI6NTAwfSwiaWF0IjoxNzQ2MTQ1NzQ3LCJleHAiOjE3NDYyMzIxNDd9.iCl3jxVihLH6Z2Oq6i1jiKtcyJ3j9kyjT676NzF7Zqs",
15 "token": "411111YJM5TX1111"
16}
17'
Response
{
"paymentId": "0090c04b-1ae8-4672-a108-32874df36f11"
}
  1. Optional Implementation: Get payment by id This endpoint allows your to get details about the payment.
Request
1curl --request GET \
2 --url https://api-sandbox.coinflow.cash/api/merchant/payments/enhanced/21d842d0-564b-4957-961e-d91ad98aa04b \
3 --header 'Authorization: YOUR_API_KEY' \
4 --header 'accept: application/json'
Response
{
"info": {
"firstName": "Dwayne",
"lastName": "Johnson",
"email": "customer@email.com",
"streetAddress": "385 Prospect Ave",
"city": "Brooklyn",
"state": "NY",
"zip": "11215",
"country": "US",
"bin": "411111",
"ip": "35.160.120.126",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"expMonth": "10",
"expYear": "30",
"ipLocation": {
"lat": "45.5235",
"lon": "-122.676",
"country": "United States",
"region": "OR",
"isp": "Amazon.com, Inc.",
"city": "Portland",
"zip": "97207"
},
"deviceInfo": {
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"browser": {
"name": "Chrome",
"version": "131.0.0.0",
"major": "131"
},
"engine": {
"name": "Blink",
"version": "131.0.0.0"
},
"os": {
"name": "Mac OS",
"version": "10.15.7"
},
"device": {
"vendor": "Apple",
"model": "Macintosh"
},
"cpu": {}
}
}
}
  1. At this point, you’ve successfully made a purchase with a new card and with a saved card. Next, lets add 3DS for card purchases. Please reach out to the Coinflow team when you’ve reached this step so we can configure 3DS on your account.

Adding 3DS to Card Checkout

Follow the below recipe to learn how to add 3DS to your new card and saved card requests.

Complete Checkout with 3DS Challenge

Adding Chargeback Protection

  1. Add the chargeback protection script to every page of your app. This script allows our provider to analyze user behavior and determine if the behavior could lead to fraud.
    • On sandbox, partnerId = COINFTEST
  2. Pass the chargebackProtectionData object to the new and saved card checkout as well as the below headers. See an example of what the request will look like when you pass chargeback protection data to the new card checkout endpoint.
    • x-device-id - Get this after adding the script in step 1
    • x-coinflow-client-ip- the payer’s ipv4 address
    • user-agent - the payer’s User Agent

  1. Get Credits Authorization Message Get a message which the payer’s wallet should sign - this authorizes them to spend the credit balance.

    curl --request POST \
    --url https://api-sandbox.coinflow.cash/api/redeem/evm/creditsAuthMsg \
    --header 'accept: application/json' \
    --header 'content-type: application/json' \
    --header 'x-coinflow-auth-blockchain: polygon' \
    --header 'x-coinflow-auth-wallet: 0xd11cc1D037B49098130BDeB592d468E3fe131240' \
    --data '
    {
    "subtotal": {
    "currency": "USD",
    "cents": 200
    },
    "transactionData": {
    "transaction": {
    "data": "0x8bf921f0",
    "to": "0x871CB657157437B602FdaAb157e4E2E277306695"
    },
    },
    "merchantId": "YOUR_MERCHANT_ID"
    }
    '
    {
    "message": "{\"domain\":{\"name\":\"Coinflow Credits Contract\",\"version\":\"1\",\"chainId\":80002,\"verifyingContract\":\"0xfcc779B1bc3b6C05406244107bAe04B858E7ED38\"},\"message\":{\"customerWallet\":\"0xd11cc1D037B49098130BDeB592d468E3fe131240\",\"creditSeed\":\"mello\",\"amount\":2000000,\"validBefore\":\"1752875597\",\"nonce\":\"0x67db071f7a1810f1e47fffea32087c46a51eaf8554bc9a44d4640f24e3035529\"},\"primaryType\":\"CreditsAuthorization\",\"types\":{\"EIP712Domain\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"chainId\",\"type\":\"uint256\"},{\"name\":\"verifyingContract\",\"type\":\"address\"}],\"CreditsAuthorization\":[{\"name\":\"customerWallet\",\"type\":\"address\"},{\"name\":\"creditSeed\",\"type\":\"string\"},{\"name\":\"amount\",\"type\":\"uint256\"},{\"name\":\"validBefore\",\"type\":\"uint256\"},{\"name\":\"nonce\",\"type\":\"bytes32\"}]}}",
    "validBefore": "1752875597",
    "nonce": "0x67db071f7a1810f1e47fffea32087c46a51eaf8554bc9a44d4640f24e3035529",
    "creditsRawAmount": 2000000
    }
  2. Sign the Message.

    const { ethers } = require("ethers");
    // Polygon testnet RPC URL
    const POLYGON_TESTNET_RPC = "https://rpc-amoy.polygon.technology";
    const provider = new ethers.providers.JsonRpcProvider(POLYGON_TESTNET_RPC);
    const privateKey = 'PAYERS_WALLET_PRIVATE_KEY';
    const wallet = new ethers.Wallet(privateKey, provider);
    const message = {
    "domain": {
    "name": "Coinflow Credits Contract",
    "version": "1",
    "chainId": 80002,
    "verifyingContract": "0xfcc779B1bc3b6C05406244107bAe04B858E7ED38"
    },
    "message": {
    "customerWallet": "0xd11cc1D037B49098130BDeB592d468E3fe131240",
    "creditSeed": "test",
    "amount": 2000000,
    "validBefore": "1752875597",
    "nonce": "0x67db071f7a1810f1e47fffea32087c46a51eaf8554bc9a44d4640f24e3035529"
    },
    "primaryType": "CreditsAuthorization",
    "types": {
    "EIP712Domain": [
    { "name": "name", "type": "string" },
    { "name": "version", "type": "string" },
    { "name": "chainId", "type": "uint256" },
    { "name": "verifyingContract", "type": "address" }
    ],
    "CreditsAuthorization": [
    { "name": "customerWallet", "type": "address" },
    { "name": "creditSeed", "type": "string" },
    { "name": "amount", "type": "uint256" },
    { "name": "validBefore", "type": "uint256" },
    { "name": "nonce", "type": "bytes32" }
    ]
    }
    }
    ;
    async function signMessage(privateKey, message) {
    const domain = message.domain; // Access the nested `domain`
    const types = { CreditsAuthorization: message.types.CreditsAuthorization };
    //const types = { Permit: message.types.Permit }; // Access the nested `types`
    const messageData = message.message; // Access the actual `message` data
    // Sign the typed data (EIP-712)
    const signedMessage = await wallet._signTypedData(domain, types, messageData);
    // Return the signed message
    return signedMessage;
    }
    signMessage(privateKey, message)
    .then((signedMessage) => {
    console.log('Signed Message:', signedMessage);
    })
    .catch((error) => {
    console.error('Error signing message:', error);
    });
  3. Send Redeem Transaction

    curl --request POST \
    --url https://api-sandbox.coinflow.cash/api/redeem/evm/sendGaslessTx \
    --header 'accept: application/json' \
    --header 'content-type: application/json' \
    --header 'x-coinflow-auth-blockchain: polygon' \
    --header 'x-coinflow-auth-wallet: 0xd11cc1D037B49098130BDeB592d468E3fe131240' \
    --data '
    {
    "subtotal": {
    "currency": "USD",
    "cents": 200
    },
    "transactionData": {
    "transaction": {
    "data": "0x8bf921f0",
    "to": "0x871CB657157437B602FdaAb157e4E2E277306695"
    }
    },
    "signedMessages": {
    "permitCredits": "0xd89875c0a956a1b372fa485a90d3d1f5e1b7a6c4d572c47d67df7317c50b73a936bc552cfbbc6cdf260808f103383fe46b2e5b940d0a90465f1fc3c1addbe82b1c"
    },
    "merchantId": "YOUR_MERCHANT_ID",
    "creditsRawAmount": 2000000,
    "nonce": "0x67db071f7a1810f1e47fffea32087c46a51eaf8554bc9a44d4640f24e3035529",
    "validBefore": "1752875597"
    }
    '
    {
    "hash": "0x20eddfe4e37c49c76cc3f6047197e4478bc41d90467279012961a4ef50b30284"
    }