How To: Implement Chargeback Protection

Developers can use this documentation to implement chargeback protection for all card checkouts.

Overview

Coinflow provides multiple ways to protect merchant accounts against fraud. Learn more about fraud prevention methods before you start implementing chargeback protection.

How to Add Chargeback Protection

When merchants opt in for chargeback protection, they need to install Coinflow Purchase Protection across every page of their site. This integration gathers device and session signals during the customer’s shopping experience so Coinflow can score the purchase for fraud and chargeback risk. Depending on your implementation method, select from the options below for setup instructions:

  1. Add the <CoinflowPurchaseProtection> component to every page on your site.
  2. Add your merchantId as a property to the <CoinflowPurchaseProtection> component.
  3. In every <CoinflowPurchase> component, add the chargebackProtectionData property and input information about each purchase made via Coinflow. See Getting the Device ID if you call Coinflow APIs directly.

Coinflow provides a mobile module for both iOS and Android that exposes a getDeviceId method. Coinflow’s integrations team will share the module, sample diff files, and the application credentials needed to initialize it on sandbox and production.

Implementation

  1. Install the mobile module Coinflow provides and follow the README to wire it into your iOS and Android builds.
  2. Initialize the module on app launch using the application credentials supplied by Coinflow. The same credentials are used in sandbox and production.
  3. Call the module’s getDeviceId method to retrieve the device ID.
  4. In {"<CoinflowPurchase>"} add the chargebackProtectionData property and add information about every purchase that is being made via Coinflow, and pass the deviceId through to the component. See Getting the Device ID below.
  1. Add the following code to the <head> of every page on your site — not just the checkout page. After completing the chargeback protection questionnaire, Coinflow will provide your production partnerId. Use COINFTEST on sandbox.
1{"<script src=\"https://sdk.nsureapi.com/sdk.js\"> </script>"}
2<script>
3 window.nSureAsyncInit = function(deviceId) {
4 window.nSureSDK.init({
5 appId: '9JBW2RHC7JNJN8ZQ', // Remains the same on sandbox and prod
6 partnerId: 'COINFTEST' // Use COINFTEST on sandbox. Coinflow assigns your prod partnerId
7 });
8 };
9</script>

📘 This script gathers information about the user’s device, how they interact with your website, and other signals that let Coinflow’s models predict the risk of fraud or chargeback for this particular user.

  1. To each of your API calls, add the x-device-id header. Pass the value returned by calling window?.nSureSDK?.getDeviceId() on your website. See Getting the Device ID below.

This deviceId is how Coinflow ties an individual request back to the device and session signals collected by the script you installed above.

  1. In the Checkout Endpoint and the Redeem Transaction Endpoint, pass the chargebackProtectionData.

📘 This information describes what is being purchased, which lets Coinflow’s models determine the risk of chargeback for this particular purchase.

Getting the Device ID

When chargeback protection is enabled, pass the device ID in the x-device-id header on checkout, redeem, and subscription API calls. How you retrieve it depends on your integration:

After the protection script has loaded and initialized on the page, read the device ID before making your Coinflow API request:

1const deviceId = window?.nSureSDK?.getDeviceId();
2
3// Include on Coinflow API requests
4headers: {
5 'x-device-id': deviceId,
6}

Mount <CoinflowPurchaseProtection> on every page, then use the useCoinflowProtectionHeaders hook from @coinflowlabs/react:

1import {
2 CoinflowPurchaseProtection,
3 useCoinflowProtectionHeaders,
4} from '@coinflowlabs/react';
5
6function App() {
7 return (
8 <>
9 <CoinflowPurchaseProtection
10 coinflowEnv="sandbox"
11 merchantId="your-merchant-id"
12 />
13 {/* Your app content */}
14 </>
15 );
16}
17
18function Checkout() {
19 const getProtectionHeaders = useCoinflowProtectionHeaders();
20 const deviceId = getProtectionHeaders()['x-device-id'];
21
22 // Include on Coinflow API requests
23 headers: {
24 ...getProtectionHeaders(),
25 }
26}

If you use <CoinflowPurchase>, the device ID is sent automatically — you only need to retrieve it manually when calling Coinflow APIs directly from your backend-for-frontend or custom checkout flow.

Coinflow provides a native module for iOS and Android. Initialize it on app launch using the credentials Coinflow supplies, then call getDeviceId and pass the result to <CoinflowPurchase> or your API layer:

1import { CoinflowPurchase } from '@coinflowlabs/react-native';
2
3// After initializing the native module at app launch:
4const deviceId = await nativeModule.getDeviceId();
5
6<CoinflowPurchase
7 deviceId={deviceId}
8 chargebackProtectionData={[/* ... */]}
9 {/* other props */}
10/>

Contact Coinflow’s integrations team for the module, sample diff files, and initialization credentials.

What to pass into chargebackProtectionData

Merchants that opt-in for chargeback protection are required to pass chargebackProtectionData as a prop to the <CoinflowPurchase> component or to our card checkout, saved card checkout, ach checkout , and redeem transaction endpoints.

🚧 The more information that you pass here the better the authorization rates will be, so it is in your best interest to supply as much information as possible

Example of chargebackProtectionData data structure

1{
2 /**
3 * The name of the product
4 */
5 productName: string;
6 /**
7 * The product type. Possible values include: inGameProduct, gameOfSkill, dataStorage, computingResources, sportsTicket, eSportsTicket, musicTicket, conferenceTicket, virtualSportsTicket, virtualESportsTicket, virtualMusicTicket, virtualConferenceTicket, alcohol, DLC, subscription, fundACause, realEstate, computingContract, digitalArt, topUp
8 * Contact Coinflow for the productType value.
9 */
10 productType: 'inGameProduct' |
11 'gameOfSkill' |
12 'dataStorage' |
13 'computingResources' |
14 'sportsTicket' |
15 'eSportsTicket' |
16 'musicTicket' |
17 'conferenceTicket' |
18 'virtualSportsTicket' |
19 'virtualESportsTicket' |
20 'virtualMusicTicket' |
21 'virtualConferenceTicket' |
22 'alcohol' |
23 'DLC' |
24 'subscription' |
25 'fundACause' |
26 'realEstate' |
27 'computingContract' |
28 'digitalArt' |
29 'topUp';
30 /**
31 * The number of units sold
32 */
33 quantity: number;
34 /**
35 * Any additional data that the store can provide on the product, e.g. description, link to image, etc.
36 */
37 rawProductData?: { [key: string]: any };
38}

Example Implementation on Coinflow’s Prebuilt UI

1<CoinflowPurchase
2 wallet={wallet}
3 merchantId={process.env.REACT_APP_MERCHANT_ID as string}
4 transaction={transaction}
5 amount={amount}
6 chargebackProtectionData={[{
7 "productName": "Sword", // Name of Product
8 "productType": "inGameProduct", // Get the value from Coinflow
9 "quantity": 1,
10 "rawProductData": { // Adjust based on the available product data
11 "productID": "sword12345",
12 "productDescription": "A legendary sword with magical powers.",
13 "productCategory": "Weapon",
14 "weight": "15 lbs",
15 "dimensions": "40 in x 5 in",
16 "origin": "Ancient Kingdom",
17 "craftedBy": "Master Blacksmith",
18 "craftingDate": "2024-06-19"
19 }
20 },]}
21/>

Example Implementation on Coinflow’s APIs

$curl --request POST \
> --url https://api-sandbox.coinflow.cash/api/checkout/ach/merchantId \
> --header 'accept: application/json' \
> --header 'content-type: application/json' \
> --data '
>{
> "subtotal": {
> "cents": 100
> },
> "token": "5a000000-0000-0000-0000-000000000000",
> "chargebackProtectionData": [
> {
> "productType": "inGameProduct",
> "productName": "Sword",
> "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"
> }
> }
> ]
>}
>'