A Yodl Checkout checkout page can be configured as follows:
webshop.eth
me.yodl
to store your Yodl Pay configuration:{
"tokens" : "USDC,USDT",
"chainIds" : "base,arb1,oeth", // also numeric chainIds are accepted
"webhookUrl" : "<https://mywebshop.com/webhook/yodl>",
"redirectUrl" : "<https://mywebshop.com/success>" // appends ?txHash=..&chainId=..
}
https://app.ens.domains/yodlhaus.eth?tab=records for an example json.
ENS_NAME = "webshop.eth"
orderId = "order_123"
amount = "10.00"
url = "<https://yodl.me/${ENS_NAME}?memo=${orderId}&amount=${amount}¤cy=USD>"
<a href={url} target="_blank">Yodl-de-hoo</a>
The payment screen will hard-code the amount and the memo.
After user pays
redirectUrl
. txHash, chainId, memo
are appended as query parameters.webhookUrl
configured in your ENS. Following JSON payload is sent.{ "chainId" : 137, "txHash" : "0x123..."}
Your webhook handler then does a POST request to https://yodl.me/api/tx/:txHash/:chainId
to retrieve the deserialized human/machine readable JSON from the transaction data.
POST <https://yodl.me/api/tx/:txHash/:chainId>
{
chainId: 137,
txHash: "0x123",
amountGross: "1000" // in minor units (cents), 10.00$,
yodlFee: "0.02", // in minor units (cents), 9.95,
amountNet: "9.98", // what you actually received: amountGross - yodlFee
tokenAddress: "0x...",
tokenIdentifier: "USDC", // unique by yodl.
memo: "order_123", // so you can match payment to your order
receiver: "0x...", // your address
sender: "0x...", // originator
// ...
}
app.post("webhook/yodl", (data) => {
const json = await fetch(`https://yodl.me/api/tx/${data.txHash}/${data.chainId}`)
// ensure money was sent to your address
assert(json.receiver == YOUR_RECEIVER_ADDRESS);
// ensure that USDC was sent (and not SHIB)
assert(json.tokenIdentifier == YOUR_TOKEN);
// ensure that no only your accepts chain was used
assert(YOUR_CHAIN_IDS.includes(json.chainId));
// fetch your order with supplied memo from your DB
order = db.select({ orderId: json.memo })
// ensure that correct amount was sent
assert(order.invoiceAmount == json.amountGross)
// all good. release order
finalizeOrder( order )
})
<aside> 🚨
You MUST verify all of the above parameters as a user can modify them.
</aside>
Reorgs currently have to be handled by the merchant. For chains where reorgs are common we recommend to wait until enough confirmations happen.