How to Claim USDT for STRIPE transaction

Claim Process

The settlement of Stripe payment revenue follows the policy here.

  1. Retrieve an information for creating transaction for the claim from the Dapp Portal.

  2. Sign the transaction using the address currently receiving Kaia-based settlements.

  3. Broadcast signed transaction.

    1. If fee delegation is enabled, transfer the signed transaction to the Fee Payer Server.

    2. If fee delegation is not used, broadcast the signed transaction directly to a Kaia node.

API to retrieve information to create unsigned transaction

Request API to receive STRIPE payment revenue in USDT

API Path

get /api/b2b-v1/dapp-settlements/{client_id}/signed-receivable

Domain

https://api.dappportal.io

Path

/api/b2b-v1/dapp-settlements/{client_id}/signed-receivable

Authentication Information

This API requires Dapp Portal authentication.

Please include the following information in the request headers for authentication

Name
Description

client_id *required string (path)

Client identifier string (36 bytes) obtained from support team

X-Auth-Client-Id *required string (header)

Client identifier string (36 bytes) obtained from support team

X-Auth-Timestamp *required string (header)

Current time in Unix epoch format

X-Auth-Salt *required string (header)

Randomly generated UUID string (36 bytes)

X-Auth-Signature *required string (header)

(*) HMAC-based signature proving request authenticity

(*) base64encode(hmac("{clientId}|GET|/api/b2b-v1/dapp-settlements/{clientId}/signed-receivable|{timestamp}|{salt}"))

Response

field
type
description
example

transaction

  • to

String

contract address to call

"0xdce5..."

  • value

String

native token's amount to send

"0x0"

  • data

String

data of smart contract

"0x...."

{
  "receivable": {
    "claimer_id": "",
    "sequence_begin": "",
    "sequence_end": "",
    "vault_address": "",
    "recipient_address": "",
    "token_address": "",
    "amount": "",
    "deadline": ""
  },
  "signature": "",
  "transaction": {
    "to": "",
    "data": "",
    "value": ""
  }
}

Sample Code

Retrieve transaction executing load() function from Dapp Portal

function toBase64(buffer) {
    const bytes = new Uint8Array(buffer);
    let binary = '';
    for (let b of bytes) {
        binary += String.fromCharCode(b);
    }
    return btoa(binary);
}
 
async function calcHmac(clientSecret, clientId, method, path, timestamp, salt) {
    const msg = `${clientId}|${method.toUpperCase()}|${path}|${timestamp}|${salt}`;
    const enc = new TextEncoder();
    const key = await crypto.subtle.importKey(
        'raw',
        enc.encode(clientSecret),
        {name: 'HMAC', hash: {name: 'SHA-256'}},
        false,
        ['sign'],
    );
    const sig = await crypto.subtle.sign('HMAC', key, enc.encode(msg));
    return toBase64(sig);
}
 
async function load(domain, clientId, clientSecret) {
    const request = {
        method: 'GET',
        path: `/api/b2b-v1/dapp-settlements/${clientId}/signed-receivable`,
        timestamp: Math.floor(Date.now() / 1000).toString(),
        salt: crypto.randomUUID()
    };
 
    // prepare the hmac
    const signature = await calcHmac(
        clientSecret,
        clientId,
        request.method,
        request.path,
        request.timestamp,
        request.salt,
    );
 
    // load the transaction
    const response = await fetch(
        `${domain}${request.path}`, {
            method: request.method,
            headers: {
                'X-Auth-Client-Id': clientId,
                'X-Auth-Timestamp': request.timestamp,
                'X-Auth-Salt': request.salt,
                'X-Auth-Signature': signature,
            },
        });
    return await response.json();
}

Create and Sign Transaction

  1. Create transaction with response from Dapp Portal.

    1. to, value, data

  2. Sign the transaction using the address currently receiving Kaia-based settlements.

  3. Broadcast signed transaction.

    1. If fee delegation is enabled, transfer the signed transaction to the Fee Payer Server.

      1. Path: /api/signAsFeePayer

      2. POST (application/json) { userSignedTx: {rawSignedTx} }

      3. Add type: 49 while creating transaction to use fee delegation

    2. If fee delegation is not used, broadcast the signed transaction directly to a Kaia node.

Sample Code

⚠️ This sample code applies to cases where the Kaia Wallet (Web Extension) is used.

If you choose to sign the unsigned transaction (obtained via API) using a different method, please make sure to use the signing method appropriate for your chosen approach.

async function connect() {
    const provider = window.klaytn;
    await provider.request({
        method: 'klay_requestAccounts',
        params: [],
    });
}

#In case of broadcasting signed tx directly
async function claim(transaction) {
    // sign the transaction
    const provider = window.klaytn;
    const gasPrice = await provider.send('klay_gasPrice', []);
    const sufficientGas = '0x40000';
    const tx = {
        from: provider.selectedAddress,
        to: transaction.to,
        data: transaction.data,
        value: transaction.value,
        gasPrice: gasPrice.result,
        gas: sufficientGas,
    };
    return await provider.send('klay_sendTransaction', [tx]);
}
 
#In case of broadcasting signed tx wih fee delegation server
async function claimFeeDelegated(domain, transaction) {
    // sign the transaction
    const provider = window.klaytn;
    const gasPrice = await provider.send('klay_gasPrice', []);
    const sufficientGas = '0x40000';
    const tx = {
        type: 49,
        from: provider.selectedAddress,
        to: transaction.to,
        data: transaction.data,
        value: transaction.value,
        gasPrice: gasPrice.result,
        gas: sufficientGas,
    };
    const signedTx = await provider.send('klay_signTransaction', [tx]);
 
    // send the signed transaction to the fee delegation server
    const response = await fetch(`${domain}/api/signAsFeePayer`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            userSignedTx: {raw: signedTx.result.rawTransaction},
        }),
    });
    return await response.json();
}

Complete Example: From Claim to Broadcast

⚠️ The example code provided is for illustrative purposes only. You should review and modify it appropriately to ensure it fits securely within your production environment. We do not take any responsibility for issues or damages caused by using this code as-is.

function toBase64(buffer) {
    const bytes = new Uint8Array(buffer);
    let binary = '';
    for (let b of bytes) {
        binary += String.fromCharCode(b);
    }
    return btoa(binary);
}
 
async function calcHmac(clientSecret, clientId, method, path, timestamp, salt) {
    const msg = `${clientId}|${method.toUpperCase()}|${path}|${timestamp}|${salt}`;
    const enc = new TextEncoder();
    const key = await crypto.subtle.importKey(
        'raw',
        enc.encode(clientSecret),
        {name: 'HMAC', hash: {name: 'SHA-256'}},
        false,
        ['sign'],
    );
    const sig = await crypto.subtle.sign('HMAC', key, enc.encode(msg));
    return toBase64(sig);
}
 
async function connect() {
    const provider = window.klaytn;
    await provider.request({
        method: 'klay_requestAccounts',
        params: [],
    });
}
 
async function load(domain, clientId, clientSecret) {
    const request = {
        method: 'GET',
        path: `/api/b2b-v1/dapp-settlements/${clientId}/signed-receivable`,
        timestamp: Math.floor(Date.now() / 1000).toString(),
        salt: crypto.randomUUID()
    };
 
    // prepare the hmac
    const signature = await calcHmac(
        clientSecret,
        clientId,
        request.method,
        request.path,
        request.timestamp,
        request.salt,
    );
 
    // load the transaction
    const response = await fetch(
        `${domain}${request.path}`, {
            method: request.method,
            headers: {
                'X-Auth-Client-Id': clientId,
                'X-Auth-Timestamp': request.timestamp,
                'X-Auth-Salt': request.salt,
                'X-Auth-Signature': signature,
            },
        });
    return await response.json();
}
 
async function claim(transaction) {
    // sign the transaction
    const provider = window.klaytn;
    const gasPrice = await provider.send('klay_gasPrice', []);
    const sufficientGas = '0x40000';
    const tx = {
        from: provider.selectedAddress,
        to: transaction.to,
        data: transaction.data,
        value: transaction.value,
        gasPrice: gasPrice.result,
        gas: sufficientGas,
    };
    return await provider.send('klay_sendTransaction', [tx]);
}
 
async function claimFeeDelegated(domain, transaction) {
    // sign the transaction
    const provider = window.klaytn;
    const gasPrice = await provider.send('klay_gasPrice', []);
    const sufficientGas = '0x40000';
    const tx = {
        type: 49,
        from: provider.selectedAddress,
        to: transaction.to,
        data: transaction.data,
        value: transaction.value,
        gasPrice: gasPrice.result,
        gas: sufficientGas,
    };
    const signedTx = await provider.send('klay_signTransaction', [tx]);
 
    // send the signed transaction to the fee delegation server
    const response = await fetch(`${domain}/api/signAsFeePayer`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            userSignedTx: {raw: signedTx.result.rawTransaction},
        }),
    });
    return await response.json();
}

Last updated