Commerce SDK - React Native
Step 1: Obtain your API Keyβ
To get set up with API Keys please email us at support@bidali.com with your request. We will provide you with API keys for our staging and production environments.
When specifying the accepted currencies and providing balances, Bidali uses a unique internali identifier named protocol
. You can view the protocols below.
The Commerce URLs to use in the webview will be:
Environment | URL | |
---|---|---|
Staging / Testnet | https://commerce.staging.bidali.com/dapp?key=YOUR_API_KEY | https://docs.bidali.com/commerce/currencies?environment=testnet |
Production / Mainnet | https://commerce.bidali.com/dapp?key=YOUR_API_KEY | https://docs.bidali.com/commerce/currencies |
The protocol
's to use for accepted currencies / balances are listed on the following pages:
Environment | URL |
---|---|
Staging / Testnet | https://docs.bidali.com/commerce/currencies?environment=testnet |
Production / Mainnet | https://docs.bidali.com/commerce/currencies |
Step 2: Load the Commerce URL in a WebViewβ
<WebView
ref={webViewRef}
source={{ uri: COMMERCE_URL }}
onMessage={onMessage}
injectedJavaScriptBeforeContentLoaded={initialJavascript} />);
See full sample code below
Valora's integration is slightly different but is a good example of how to best to setup and interact with the webview and Bidali from React Native
Step 3: Add a bidaliProvider
onto the window and specify the paymentCurrencies
that you will be acceptingβ
window.bidaliProvider = {
key: 'YOUR API KEY', // This is provided by Bidali
name: 'YOUR WALLET NAME', // This will be provided by Bidali with your apiKey
paymentCurrencies: ['stellar', 'stellarusdc'],
email: 'test@test.com',
phoneNumber: '15554321234',
balances: {
'stellar': '5',
'usdcstellar': '20'
},
onPaymentRequest: (paymentRequest) => {
var payload = { method: 'onPaymentRequest', data: paymentRequest };
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
},
openUrl: function (url) {
var payload = { method: 'openUrl', data: { url } };
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
};
window.bidaliProvider
must have the following properties:
Property | Type | Description |
---|---|---|
name | String | The name of the wallet integrating (Provided by Bidali) |
key | String | This is your Bidali Commerce Publishable Key. The unique and public key that identifies your organization. It looks like pk_viqah4squsnuw6p0e1ue .(Provided by Bidali) |
paymentCurrencies | String[] | Allows you to only show certain cryptocurrencies as payment options. It takes an Array of String s that are the coin protocols (Bidali's unique identifier) |
limitToCountries | String[] | Country codes of the countries to limit the products to, ex: [ "US", "CA" ] |
email | String | Allows us to pre-populate their email, user has to confirm during checkout flow |
phoneNumber | String | Allows us to pre-populate the phone number for mobile topups, the user has the chance to change this |
balances | object | The balances for the allowed currencies, ex. { stellar: '25.2', usdcstellar: '2000' } |
onPaymentRequest | Function | Provide a handler for this function that displays a payment confirmation modal for the user |
openUrl | Function | Opens a URL to our support docs, etc. Ideally should open in an external browser or a new in-app modal browser |
Step 4: Handle onPaymentRequest
β
Add a handler for onPaymentRequest
that shows the user a payment confirmation modal using the information in the paymentRequest
. If an extraId
field is present on the paymentRequest
it must be sent with the transaction (ex. as a memo)
This is what a paymentRequest
looks likeβ
{
amount: '50',
symbol: 'XLM',
protocol: 'stellar', // This is Bidali's unique identifier for a currency
address: '0x220b48eda85a0a067c769f0442dd2f4e03ba625a',
chargeId: 'vIQ807gvR',
extraId: 'vIQ807gvR'
extraIdName: 'Memo text'
description: '$50 Amazon US',
lineItems: [
{
name: 'Amazon US',
quantity: 1,
amount: '$50 USD',
image: 'https://assets.bidali.com/commerce/brands/amazon-com-us.png'
}
]
}
A paymentRequest
has the following properties:
Property | Type | Description |
---|---|---|
address | String | The address to send to |
amount | String | The amount to send, as a user readable string (ex. "25") |
symbol | String | The symbol of the currency the user has chosen to pay with, ex: BTC , not unique to a currency (for instance USDC ERC20 and USDC on Stellar both have the symbol USDC ) |
protocol | String | The protocol of the currency the user has chosen to pay with, this is unique for each currency. ex: usdcstellar |
description | String | A comma-delimited list of products being purchased. Can be used on your payment approval screen so the user sees what they are approving payment for. Ex: $50 USD Amazon US, 2x $25 USD Apple US |
lineItems | Array | A list of products being purchased. Just like with description , you can use this on your payment approval screen. A line item looks like { name: 'Apple US', quantity: 1, amount: '$5 USD', image: 'https://assets.bidali.com/commerce/brands/apple.png' } |
chargeId | String | The users order reference, helpful to reference the order in the future or if there are any issues. Ex: vIQ807gvR |
extraId | String | The extraId that must be passed for the payment to be credited appropriately to the order. Currently only applicable to currencies on Stellar, Algorand, and Solana networks |
extraIdName | String | The name of the extraId that must be sent with the transaction. Currently only applicable to currencies on Stellar, Algorand, and Solana networks |
Step 5: Notify Bidali of payment statusβ
When the user sends the transaction call window.bidaliProvider.paymentSent()
inside the WebView. If they cancel payment / dismiss the modal then call window.bidaliProvider.paymentCancelled()
Step 6: Update balancesβ
After a user sends a transaction or their balances change, update the balances
object on window.bidaliProvider
by stringifying it and injecting the javascript
useEffect(() => {
webViewRef.current?.injectJavaScript(`
window.bidaliProvider.balances = ${JSON.stringify(balances)}
`)
}, [balances]);
Example codeβ
Hereβs some sample code for React Native that loads the Commerce URL in a react-native-webview, injects javascript that sets window.bidaliProvider
and handles onPaymentRequest
.
Note: Ensure the JS you inject injectedJavaScriptBeforeContentLoaded
ends with true;
as shown below or sometimes there can be silent failures.
import React, { useRef, useState, useEffect } from 'react';
import styled from 'styled-components/native';
import { WebView } from 'react-native-webview';
const Container = styled.SafeAreaView`
flex: 1;
`;
const BidaliScreen = ({ user }) => {
const [ balances, setBalances ] = useState({ stellar: '5.2', usdcstellar: '2000' });
const webViewRef = useRef(null);
const user = {
email: 'test@test.com',
phoneNumber: '15554321234'
};
const onMessage = event => {
const { method, data } = JSON.parse(event.nativeEvent.data);
switch (method) {
case 'onPaymentRequest': {
const {
amount,
address,
symbol,
protocol,
description,
chargeId,
extraId: memo
} = data;
// These 2 callbacks need to be called to notify Bidali of the status of the payment request
// so it can update the WebView accordingly.
const onPaymentSent = () => {
webViewRef.current?.injectJavaScript(`window.bidaliProvider.paymentSent();`);
};
const onPaymentCancelled = () => {
webViewRef.current?.injectJavaScript(`window.bidaliProvider.paymentCancelled();`)
};
if(protocol === 'stellar') {
// Show a native transaction confirmation modal to the user
const result = await sendXLM({ amount, address, symbol, protocol, memo });
if(result.status === 'sent') {
onPaymentSent();
} else if(result.status === 'cancelled') {
onPaymentCancelled();
}
}
break;
}
case 'openUrl': {
const { url } = data;
// Open the URL in an in-app browser or external browser
}
}
};
const initialJavascript = `
window.bidaliProvider = {
name: 'WALLET NAME', // This will be provided by Bidali with your apiKey
paymentCurrencies: ['stellar', 'usdcstellar'],
email: ${user.email ? `'${user.email}'` : null},
phoneNumber: ${user.phoneNumber ? `'${user.phoneNumber}'` : null},
balances: ${JSON.stringify(balances)},
onPaymentRequest: (paymentRequest) => {
var payload = { method: 'onPaymentRequest', data: paymentRequest };
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
},
openUrl: function (url) {
var payload = { method: 'openUrl', data: { url } };
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
};
true; // note: this is required, or you'll sometimes get silent failures
`;
useEffect(() => {
webViewRef.current?.injectJavaScript(`
window.bidaliProvider.balances = ${JSON.stringify(balances)}
`)
}, [balances]);
return (<Container>
<WebView
ref={webViewRef}
source={{ uri: 'https://commerce.staging.bidali.com/dapp?key=YOUR_API_KEY' }}
onMessage={onMessage}
injectedJavaScriptBeforeContentLoaded={initialJavascript} />
</Container>);
};
export default BidaliScreen;
Please send any feedback to support@bidali.com