Building a FonBnk on‐ramp service with webhooks - pasosdeJesus/stable-sl GitHub Wiki

Following https://docs.fonbnk.com/on-ramp/integration-guide

Test complete Webhook V1:

request.headers= Headers {                                                      
  'x-forwarded-for': '35.202.239.140', 
  'x-forwarded-proto': 'https',                                                                                                                                 
  host: 'stable-sl.pdj.app',                                                    
  connection: 'close',                                                                                                                                          
  'content-length': '561',                                                      
  accept: 'application/json, text/plain, */*',                                  
  'content-type': 'application/json',                                                                                                                           
  'user-agent': 'axios/1.7.9',                                                  
  'accept-encoding': 'gzip, compress, deflate, br',
  'x-forwarded-host': 'stable-sl.pdj.app',                                                                                                                      
  'x-forwarded-port': '3000'            
}
request.json()= {     
  data: {                               
    status: 'complete',                 
    orderId: '6475d8b5cbece07a5614dc53',
    phoneNumber: '234962469394',
    amount: 5.2,                        
    localCurrencyAmount: 4706,  
    localCurrencyIsoCode: 'NGN',
    countryIsoCode: 'NG',     
    provider: 'bank_transfer',
    network: 'SOLANA',                                                          
    address: '53L9ahwHcNnD4F11TqNHQgVUa75WgaCL2WGeiKiK2gCc',
    memo: '',       
    orderParams: '',                                                            
    carrierId: '67dd2a35ab899e32e7ac3758',                                      
    hash: 'WBwtQK4C49wa6hFYsKNnLDC3WbfH3mpQqWqAEQn6bdQjhvMsjQvXoqDh1qdMXtDDVcoHJvyKw4H9htubdDc3sgc',
    date: '2025-03-23T09:51:38.488Z'
  },
  hash: 'f65bb3025653d3b7fc3159b55ca9e6c83903d98e6904012d7b1f617e049a02cb'
}

Test complete Webhook V2:

request.headers= Headers {
  'x-forwarded-for': '35.202.239.140',
  'x-forwarded-proto': 'https',
  host: 'stable-sl.pdj.app',
  connection: 'close',
  'content-length': '487',
  accept: 'application/json, text/plain, */*',
  'content-type': 'application/json',
  'x-signature': '18ef8a194c712738e3ce13e9302c425b2726752d4dd2141fbe1f96711a088186',
  'user-agent': 'axios/1.7.9',
  'accept-encoding': 'gzip, compress, deflate, br',
  'x-forwarded-host': 'stable-sl.pdj.app',
  'x-forwarded-port': '3000'
}
request.json()= {                            
  data: {                                                                       
    status: 'complete',                                                         
    orderId: '6475d8b5cbece07a5614dc53',
    phoneNumber: '234962469394',        
    amount: 5.2,                        
    localCurrencyAmount: 4706,                                                  
    localCurrencyIsoCode: 'NGN',       
    countryIsoCode: 'NG',                                                                                                                                       
    provider: 'bank_transfer',                                                  
    network: 'SOLANA',                                                                                                                                          
    address: '53L9ahwHcNnD4F11TqNHQgVUa75WgaCL2WGeiKiK2gCc',                    
    memo: '',                                                                   
    orderParams: '',                                                                                                                                            
    carrierId: '67dd29f0ff7b3d070995e6ad',                                      
    hash: 'WBwtQK4C49wa6hFYsKNnLDC3WbfH3mpQqWqAEQn6bdQjhvMsjQvXoqDh1qdMXtDDVcoHJvyKw4H9htubdDc3sgc',
    date: '2025-03-23T09:55:53.914Z'                                                                                                                            
  }                                     
} 

I used Webhoooks V2, and used my development wallet in the sandbox.

Take note ot the Source Param by adding it in .env

We notice that the Sandbox Pay Widget supports two big methods of on-ramp:

  1. Bank Trasnfer
  2. Air Time

In our humble opinion Orage Money of Sierra Leone is more like a Bank Transfer.

Buying a stable with FonBnk will send several requests each one with its onw x-signature in header

'x-signature': 'b90ddbfc7d975f32ce4f826485fc3ed0c72e4bbbe931de3ccf868af9e3ad7fae',

And 5 requests with the following common json fields:

    orderId: '67dfea5b4671fb2dcf105219',                                        
    phoneNumber: '2347000000007',                                                                                                                               
    localCurrencyAmount: 4869,                                                  
    localCurrencyIsoCode: 'NGN',                                                                                                                                
    countryIsoCode: 'NG',                                                       
    provider: 'carrier',                                                        
    amount: 3,                                                                                                                                                  
    amountCrypto: 3,                    
    network: 'CELO',                                                                                                                                            
    asset: 'CUSD',                                                              
    address: '0x6b3bc1b55b28380193733a2fd27f2639d92f14be',                      
    memo: null,                                                                                                                                                 
    orderParams: null,                  
    carrierId: '618e43914f57e07d255ff351'

that will start only after the buyer starts the transfer: image

Beside date, the fields status and resumeUrl change and the last 2 add hash:

  1. Swap Initiated
    status: 'swap_initiated',                                                   
    resumeUrl: 'https://sandbox-pay.fonbnk.com/ussd/67dfea5b4671fb2dcf105219',                                                                                  
  1. Swap Buyer Confirmed
    status: 'swap_buyer_confirmed',                                             
    resumeUrl: 'https://sandbox-pay.fonbnk.com/swap-status?orderId=67dfea5b4671fb2dcf105219',
  1. Swap Seller Confirmed
    status: 'swap_seller_confirmed',                                                                                                                            
    resumeUrl: 'https://sandbox-pay.fonbnk.com/swap-status?orderId=67dfea5b4671fb2dcf105219',
  1. Pending
    status: 'pending',                                                          
    hash: '0x6fa8c533fa09081cbd15f77af5a90dd8ac1c20a0bebac2227a7b3a475ef6e81c',
    resumeUrl: 'https://sandbox-pay.fonbnk.com/swap-status?orderId=67dfea5b4671fb2dcf105219',
  1. Complete
    status: 'complete',                                                                                                                                         
    hash: '0x6fa8c533fa09081cbd15f77af5a90dd8ac1c20a0bebac2227a7b3a475ef6e81c',
    resumeUrl: 'https://sandbox-pay.fonbnk.com/swap-status?orderId=67dfea5b4671fb2dcf105219',
    carrierId: '618e43914f57e07d255ff351'

For bank transfers the order is the same but it changes:

provider: 'bank_transfer',

The hash correspond to the transaction on the blockchain: https://alfajores.celoscan.io/tx/0x43a6c1c36cce23bc213d77cbddecb269809547fc29c2d740ee5c8a8691760a30

The details of the completed order of the widget give more details of the agent and the transaction:

image

And link to the provided receipt in googleapis: https://storage.googleapis.com/fonbnk-user-receipts/2a72fe10-e9dc-4643-aebf-1cc93b61a225

Regarding exchange rate, today I see 1USD=1550NGN while FonBnk uses 1USDT=1573.5NGN, arond 1.5% above official rate. It says that the fee is 0, although in the https://sandbox-dashboard.fonbnk.com/offramp/settingsi it says that it charges in CEL 2.5% It is