> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.coinflow.cash/guides/checkout/implementation-overview/implementation-guides/advanced-use-cases/credit-purchase-usdc-to-byo-wallet-evm/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 BYO Wallet (EVM) > **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. ## Summary This implementation guide outlines how Merchants on EVM chains can accept pay-ins and settle to a Merchant's EVM wallet. ## 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 EVM Contract work](/guides/checkout/settlement-locations/settlement-to-contracts/settle-to-evm-contract/implement-settlement-to-evm-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 Implementation ### React SDK 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: ' \ --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: ' \ --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: ' \ --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: ' \ --header 'content-type: application/json' \ --data ' { "eventType": "BuyerChallenge", "type": "thirdPartyKyc", "status": "successfullyFulfilled", "customerId": "user-123-abc", "country": "US", "email": "dwaynejohnson@gmail.com" } ' ``` For full descriptions and timing guidance for each event, see [Sending Payer Events](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events). 2. Install Coinflow package * `npm i @coinflowlabs/react` 3. [Tokenize the checkout parameters.](/api-reference/api-reference/checkout/get-checkout-jwt-token) This encrypts the checkout parameters so bad actors cannot tamper with the checkout args. **`Request`** ```curl Request curl --location 'https://api-sandbox.coinflow.cash/api/checkout/jwt-token' \ --header 'Authorization: YOUR_API_KEY' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data-raw ' { "webhookInfo": { "example": "{\"nftId\":\"123abc\"}" }, "subtotal": { "currency": "USD", "cents": 100 }, "transactionData": { "destination": "0x...", // Whitelisted merchant wallet address "type": "token" }, "email": "payer@gmail.com", "blockchain": "base", "chargebackProtectionData": [ { "productName": "My Product", "quantity": 1, "rawProductData": { "example": "{\"description\":\"description of nft\"}" }, "productType": "inGameProduct" // This will change on prod } ], "deviceId": "123456789" "settlementType": "Credits" } ' ``` **`Response`** ```Text Response { "checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguCjgOKYgueAleiAnN2j5IGM4LGn46CD5oOb4LCF44CQ7Iqy4YCF6KSz4KCI7KaczLDGkOuhgNqE44iA7rWwybDgp6DHgOCumeawgOSQqeSio0LgsJ3njaPmoYXItOa1ku6AjOyFieKmlOiTke67iOWCguWxiOmroOSNuO65suOou-mUremsreWZqOSytueBrOeBpOGgqOSZiOaxrOKhiOiRpOmitOGxiOG7vuuYnOeDmOeBjOChhuCglOuTiOunuOyYlOawmOqXtuujvuSyuuuSnOy7mOqglOSZqOahpOeVrOiwmOShsOKglOaphuGhjOuXjeiRhuaStOSZjFx1ZGQxY-K7k-uQlFx1ZDg2NO-kqOmUq-qHg-6Xqu-pmuySoeGxhuSVhueDquqYiOmHlOShmuGzmOKgnOaikeSuuFx1ZGExOOebvuKisuuguOiSqdOD4LCy4Y6B7IqZ5LO045Cb6qeM4o2D6Iyc7KOR4ZKt4ZyC6I2h6oCy44SMzZPSheyHmeixmOOyhsyE5IWC7oCo5LCO46uJ0rfvg6Dos6jMmOWqguiMi-qSjOu4nOqdkuivsuerpeWljOGmlemCi-6ZmeyFsOuItOCouuKDpeqCoeuAnOiImeGciuyNqeaIiuSxseWkrtek64S4XHVkODRi4YiN6LqnwqDngLjojJrhnIzsrYLpm43rqI3jjKbotoztmJjigYLlkoTihILoloXpi5HtkafijJHolZTogYLosoHnlZvmmonohYDnhbHooLTrjIXcr-mWou2GsOSwsuGchOm6g-qrmOGBmeieoOyfoemhiOWBsOGSqeWohOyzkO6rm-yhmeOQrOaAq-STqeGnpuSxteCoquWSgO6JkuqwnuGBmtys6Yax4rGQ5JS46rSH6ICF74iAIiwibWVyY2hhbnRJZCI6InRlc3R0ZXN0IiwiaWRlbXBvdGVuY3lLZXkiOiJJSzVlZWE3YzI3LWEyMjgtNDcyMC1iYTVkLWI1ZDA0ZDUzMzA3MCIsInN1YnRvdGFsIjp7ImN1cnJlbmN5IjoiVVNEIiwiY2VudHMiOjUwMH0sImlhdCI6MTc0Mjg1NTY3OCwiZXhwIjoxNzQyOTQyMDc4fQ.2dGfWnazfyHaz_uEWKM9RU-jh-tXUSMPFZJdNvmMPwo" } ``` 4. Implement `CoinflowPurchase` component ```javascript Promise<{hash: string}>; // This isn't technically needed as the end user's wallet is never sending a transaction signMessage: (message: string) => Promise; }} merchantId={'YOUR_MERCHANT_ID'} // Replace with your merchant ID env={'sandbox || prod'} onSuccess={(...args) => console.log('Purchase Success', args)} blockchain={'base'} subtotal={{cents: 100, currency: Currency.USD}} // Purchase amount in usdc jwtToken = {'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguCjgOKYgueAleiAnN2j5IGM4LGn46CD5oOb4LCF44CQ7Iqy4YCF6KSz4KCI7KaczLDGkOuhgNqE44iA7rWwybDgp6DHgOCumeawgOSQqeSio0LgsJ3njaPmoYXItOa1ku6AjOyFieKmlOiTke67iOWCguWxiOmroOSNuO65suOou-mUremsreWZqOSytueBrOeBpOGgqOSZiOaxrOKhiOiRpOmitOGxiOG7vuuYnOeDmOeBjOChhuCglOuTiOunuOyYlOawmOqXtuujvuSyuuuSnOy7mOqglOSZqOahpOeVrOiwmOShsOKglOaphuGhjOuXjeiRhuaStOSZjFx1ZGQxY-K7k-uQlFx1ZDg2NO-kqOmUq-qHg-6Xqu-pmuySoeGxhuSVhueDquqYiOmHlOShmuGzmOKgnOaikeSuuFx1ZGExOOebvuKisuuguOiSqdOD4LCy4Y6B7IqZ5LO045Cb6qeM4o2D6Iyc7KOR4ZKt4ZyC6I2h6oCy44SMzZPSheyHmeixmOOyhsyE5IWC7oCo5LCO46uJ0rfvg6Dos6jMmOWqguiMi-qSjOu4nOqdkuivsuerpeWljOGmlemCi-6ZmeyFsOuItOCouuKDpeqCoeuAnOiImeGciuyNqeaIiuSxseWkrtek64S4XHVkODRi4YiN6LqnwqDngLjojJrhnIzsrYLpm43rqI3jjKbotoztmJjigYLlkoTihILoloXpi5HtkafijJHolZTogYLosoHnlZvmmonohYDnhbHooLTrjIXcr-mWou2GsOSwsuGchOm6g-qrmOGBmeieoOyfoemhiOWBsOGSqeWohOyzkO6rm-yhmeOQrOaAq-STqeGnpuSxteCoquWSgO6JkuqwnuGBmtys6Yax4rGQ5JS46rSH6ICF74iAIiwibWVyY2hhbnRJZCI6InRlc3R0ZXN0IiwiaWRlbXBvdGVuY3lLZXkiOiJJSzVlZWE3YzI3LWEyMjgtNDcyMC1iYTVkLWI1ZDA0ZDUzMzA3MCIsInN1YnRvdGFsIjp7ImN1cnJlbmN5IjoiVVNEIiwiY2VudHMiOjUwMH0sImlhdCI6MTc0Mjg1NTY3OCwiZXhwIjoxNzQyOTQyMDc4fQ.2dGfWnazfyHaz_uEWKM9RU-jh-tXUSMPFZJdNvmMPwo'} /> ``` 5. [Customize the UI](/guides/developer-resources/custom-branding) on [your dashboard](https://sandbox-merchant.coinflow.cash/theme) 6. [Whitelist your url](https://sandbox-merchant.coinflow.cash/frame-ancestors) 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](/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: ' \ --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: ' \ --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: ' \ --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: ' \ --header 'content-type: application/json' \ --data ' { "eventType": "BuyerChallenge", "type": "thirdPartyKyc", "status": "successfullyFulfilled", "customerId": "user-123-abc", "country": "US", "email": "dwaynejohnson@gmail.com" } ' ``` For full descriptions and timing guidance for each event, see [Sending Payer Events](/guides/checkout/payment-security-risk-management/fraud-protection/sending-payer-events). 2. [Fetch a session key](/api-reference/api-reference/authentication/get-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`** ```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-user-id: customer123' ``` **`Response`** ```Text Response { "key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y" } ``` 3. [Get the Totals for the checkout](/api-reference/api-reference/checkout/get-totals) to show the customer a quote inclusive of all fees. **`Request`** ```curl Request curl --request POST \ --url https://api-sandbox.coinflow.cash/api/checkout/totals/merchantId \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y' \ --data ' { "subtotal": { "cents": 100 }, "settlementType": "USDC" } ' ``` **`Response`** ```Text 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.](/recipes/recipes/pci-compliant-card-tokenization) See tab: `Tokenize New Card` 5. [Tokenize the checkout parameters.](/api-reference/api-reference/checkout/get-checkout-jwt-token) This encrypts the checkout parameters so bad actors cannot tamper with the checkout args. **`Request`** ```curl Request curl --request POST \ --url https://api-sandbox.coinflow.cash/api/checkout/jwt-token \ --header 'Authorization: YOUR_API_KEY' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "subtotal": { "currency": "USD", "cents": 500 }, "blockchain": "base", "settlementType": "Credits" } ' ``` **`Response`** ```Text Response { "checkoutJwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguC7gOSMgueAheiEieWIgOyCg-GglO2cgOSwg-aFiOiEmOSgiOyBljjJo-iBpuKyluSsgOyxiVx1MDAxYeGDuMea7oCE7oCT7ICD6ICX57GEwojimpDomIjis7nhrafqiYHjq7zls6Dll4HkrpflqYnvgpDuvp_IouuToeqer-aTjeGbtOuloOqLgeK0lu2RkeGiuO6xkOuDoOmEve6nqOKgqeqkme6lsOWBqO-BkeqjoOijkuKzoOykmOWlqeeGqOunseqjouKgnOWng-GiieK3suWAqeGhiu2KiOGKkeOUmOKhke-JteeAsOmBouSnmO6SuOKxkOmiieykmeeGsuiiq-qgke-HquWkmOSAgeeygCIsIm1lcmNoYW50SWQiOiJtZWxsbyIsImlkZW1wb3RlbmN5S2V5IjoiSUtiYmRkMWI1NS1iZWE3LTRkMzMtOWRkMi0wNGZhZDEwNzFiZDciLCJzdWJ0b3RhbCI6eyJjdXJyZW5jeSI6IlVTRCIsImNlbnRzIjo1MDB9LCJpYXQiOjE3NTI2MTgwOTEsImV4cCI6MTc1MjYxOTg5MX0.tBsJpIMVe0tyeLcu5xfWDKtodFoi44bQKqAckVXq5DI" } ``` 6. **[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 with a credit card. Below is an example of how you'd call the card checkout endpoint: * ```curl Request curl --location 'https://api-sandbox.coinflow.cash/api/checkout/card/mello' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --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' \ --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXQiOiIweGQxMWNjMUQwMzdCNDkwOTgxMzBCRGVCNTkyZDQ2OEUzZmUxMzEyNDAiLCJibG9ja2NoYWluIjoicG9seWdvbiIsIm1lcmNoYW50SWQiOiJtZWxsbyIsImlhdCI6MTc1MjYxODE5MSwiZXhwIjoxNzUyNzA0NTkxfQ.TVQX91Pq-xTimiSxZ6_HZP_G-TVrTmtf93cqZY34nuU' \ --header 'x-coinflow-client-ip: 64.227.3.71' \ --header 'x-device-id: 123456789' \ --data-raw ' { "subtotal": { "currency": "USD", "cents": 500 }, "card": { "cardToken": "230377JSUM3F0275", "expYear": "30", "expMonth": "10", "email": "iamapayer@gmail.com", "firstName": "Dwayne", "lastName": "Johnson", "address1": "380 Prospect Ave", "city": "Brooklyn", "zip": "11215", "state": "NY", "country": "US" }, "jwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoi456C4oKW26LXguC7gOSMgueAheiEieWIgOyCg-GglO2cgOSwg-aFiOiEmOSgiOyBljjJo-iBpuKyluSsgOyxiVx1MDAxYeGDuMea7oCE7oCT7ICD6ICX57GEwojimpDomIjis7nhrafqiYHjq7zls6Dll4HkrpflqYnvgpDuvp_IouuToeqer-aTjeGbtOuloOqLgeK0lu2RkeGiuO6xkOuDoOmEve6nqOKgqeqkme6lsOWBqO-BkeqjoOijkuKzoOykmOWlqeeGqOunseqjouKgnOWng-GiieK3suWAqeGhiu2KiOGKkeOUmOKhke-JteeAsOmBouSnmO6SuOKxkOmiieykmeeGsuiiq-qgke-HquWkmOSAgeeygCIsIm1lcmNoYW50SWQiOiJtZWxsbyIsImlkZW1wb3RlbmN5S2V5IjoiSUtiYmRkMWI1NS1iZWE3LTRkMzMtOWRkMi0wNGZhZDEwNzFiZDciLCJzdWJ0b3RhbCI6eyJjdXJyZW5jeSI6IlVTRCIsImNlbnRzIjo1MDB9LCJpYXQiOjE3NTI2MTgwOTEsImV4cCI6MTc1MjYxOTg5MX0.tBsJpIMVe0tyeLcu5xfWDKtodFoi44bQKqAckVXq5DI" } ' ``` ```Text Response { "paymentId": "f3fc8a34-680b-4b91-905b-1db5628bbb0e" } ``` 7. [Re-tokenize a saved card number.](/recipes/recipes/pci-compliant-card-tokenization) See tab: `Refresh Token w/ CVV` 8. **[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: **`Request`** ```curl Request curl --location 'https://api-sandbox.coinflow.cash/api/checkout/token/testtest' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --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' \ --header 'x-coinflow-auth-session-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkIjoiY3VzdG9tZXIxMjMiLCJtZXJjaGFudElkIjoidHlsZWUiLCJpYXQiOjE3MzQzNjY4NDksImV4cCI6MTczNDQ1MzI0OX0.rxyzFgSZNtIR7KguHyb7MFq2xeDNKH2-3NA49eHH-7Y' \ --header 'x-coinflow-client-ip: 64.227.3.71' \ --header 'x-device-id: 123456789' \ --data ' { "subtotal": { "currency": "USD", "cents": 500 }, "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", "token": "411111YJM5TX1111" } ' ``` **`Response`** ```Text Response { "paymentId": "0090c04b-1ae8-4672-a108-32874df36f11" } ``` 8. **Optional Implementation: [Get payment by id](/api-reference/api-reference/merchant/get-payment-by-id)** This endpoint allows your to get details about the payment. **`Request`** ```curl Request curl --request GET \ --url https://api-sandbox.coinflow.cash/api/merchant/payments/enhanced/21d842d0-564b-4957-961e-d91ad98aa04b \ --header 'Authorization: YOUR_API_KEY' \ --header 'accept: application/json' ``` **`Response`** ```Text 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": {} } } } ``` 9. 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](/recipes/recipes/complete-checkout-with-3-ds-challenge-react) #### Adding Chargeback Protection 1. [Add the chargeback protection script](/guides/checkout/payment-security-risk-management/fraud-protection/implement-chargeback-protection#how-to-add-chargeback-protection) 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, use the test `partnerId` provided by the Coinflow team. 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 \ 10. [Get Credits Authorization Message](/api-reference/api-reference/redeem/get-evm-credits-auth-msg) 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": { "destination": "0x...", "type": "token" }, "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 } ``` 11. 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); }); ``` 12. [Send Redeem Transaction](/api-reference/api-reference/redeem/send-evm-credits-gasless-tx) ``` 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": { "destination": "0x...", // Whitelisted merchant wallet address "type": "token" }, "signedMessages": { "permitCredits": "0xd89875c0a956a1b372fa485a90d3d1f5e1b7a6c4d572c47d67df7317c50b73a936bc552cfbbc6cdf260808f103383fe46b2e5b940d0a90465f1fc3c1addbe82b1c" }, "merchantId": "YOUR_MERCHANT_ID", "creditsRawAmount": 2000000, "nonce": "0x67db071f7a1810f1e47fffea32087c46a51eaf8554bc9a44d4640f24e3035529", "validBefore": "1752875597" } ' ``` ``` { "hash": "0x20eddfe4e37c49c76cc3f6047197e4478bc41d90467279012961a4ef50b30284" } ```