Setup powerful event-driven payment workflows in minutes.
βΉοΈ To see Webhooks in action, with code examples, check out our dev examples repository.
What are Webhooks?
Helio Webhooks allow developers to listen to Helio payment events and verify transactions on your application's backend.
Security: Webhooks are linked to your Helio account. Log in to the Helio dashboard to generate your API key. Each Webhook generates a `sharedSecret` used with the target API to authenticate the endpoints with a Bearer auth header.
Support: Webhooks are available for Helio Pay Links on Solana, Ethereum, Base, Polygon and BTC; as well as Pay Streams (recurring payments) on Solana.
Webhook payload example
Our webhooks include detailed information about the transaction and Pay Link.
{ // the PaylinkEventPayload object"transaction":"...",// JSON string of the transactionObject below"event":"CREATED",// PaylinkEvents enum - matches the webhook event type when creating the webhook"transactionObject": {"id":"65e1df4d0ce08148bc333b62",// Helio transaction ID"paylinkId":"65dc9f9f1154beaac39976c8",// Paylink ID"quantity": 1,"createdAt":"2024-03-01T13:59:41.303Z","paymentType":"PAYLINK",// or 'PAYSTREAM'"meta": { // the TransactionMeta object"id":"65e1df4d0ce08148bc333b60","amount":"9900000",// amount in minimal units (lamport/Sats/Wei)"senderPK":"Er3RwfYqCETBTf5RktezXaNDT3zYgwBMftxBYbX8Zk1G",// customer's wallet"recipientPK":"Er3RwfYqCETBTf5RktezXaNDT3zYgwBMftxBYbX8Zk1G",// merchant's recipient wallet"customerDetails": { "country":"United States","deliveryAddress":"test-address","email":"test@example.com","fullName":"test-full-name","phoneNumber":"+0123123123123","discordUsername":"a11111118100","discordUser": {"id":"1234567890","username":"test-discord-username" },"twitterUsername":"test-x-username","state":"test-state","street":"test-street","streetNumber":"123","areaCode":"90210","city":"test-city""additionalJSON": "\"{\\\"test\\\": 123}\"" // any additionalJSON will be JSON stringified },"productDetails":null,"transactionSignature":"5AYzruixQiGX8rm279cPLo7bdqaUPYMD8Z3QnBNVz2omZHaUsUKFZRmaV8W7sAHPEyExeHkjquy8mg6LHcNktg5c","transactionStatus":"SUCCESS","splitRevenue":false,"remainingAccounts": [],"totalAmount":"9900000","affiliateAmount":"0",// Amount sent to affiliate who referred the transaction. This will normally be "0" unless referred by affiliate"affiliateCode":"somecode",// Affiliate code used - this will normally be undefined"affiliatePublicKey":"Er3RwfYqCETBTf5RktezXaNDT3zYgwBMftxBYbX8Zk1G"; // Public key (wallet address) for affiliate who referred this transaction. This will normally be undefined"tokenQuote": {"from":"SOL","fromAmountDecimal":"0.01","to":"SOL","toAmountMinimal":"10000000" },"submitGeolocation":"FR",// ISO 3166-1 alpha-2 country code based on IP address which submitted the transaction to our server"currency": {"id":"63430c8348c610068bcdc474","blockchain":null } } }}
Creating a Pay Link Webhook
This is an example of a curl command to register a webhook for paylinkID: 636a74162e72d4ad24ac9ce9 triggered by the CREATED event upon transaction confirmation.
This sends a POST request to targetUrl: https://target-url.com/post-endpoint.
Note: For Pay Link web hooks CREATED is the only event. It's fired when the transaction is confirmed on the blockchain and within Helio's system (near-instant for Solana).
The response of this request will look as follows:
A unique token generated at webhook creation is included with each webhook as authorization: Bearer SHARED_TOKEN, verifying the webhook source as Helio.
Note: Retain this token to authenticate and delete web hooks if needed.
Upon successful payment on Pay Link 636cf9c095aeedb263968ee9, the targetUrl will receive an HTTP [POST] request with the following payload:
classPaylinkEventPayload { event:PaylinkEvents; // e.g. 'CREATED' transaction:string; // JSON string value of the transactionObject transactionObject:Transaction;}classTransaction { id:string; paylinkId:string; quantity:number; fee?:string; createdAt:string; paymentType:PaymentRequestType; claimDetails: { tradingView?: { username:string; }; discord?: { username:string; }; }; meta:TransactionMeta;}enumTransactionStatus { INITIATED ='INITIATED', PENDING ='PENDING', SUCCESS ='SUCCESS', FAILED ='FAILED', CANCELED ='CANCELED', SETTLED ='SETTLED',}classTransactionMeta { id:string; transactionSignature:string; // transaction hash on the blockchain amount:string; recipientPK:string; // merchant's public key (wallet address) senderPK:string; // customer's public key (wallet address) customerDetails: { email?:string; discordUsername?:string; discordUser?: { id:string username:string } twitterUsername?:string; fullName?:string; country?:string; deliveryAddress?:string; phoneNumber?:string; street?:string; streetNumber?:string; city?:string; state?:string areaCode?:string; additionalJSON?:string; }; productDetails: { // From 'advanced options' (step 3 of paylink creation) -> additional information name?:string; value?:string; }; splitRevenue:boolean; remainingAccounts: { amount:string; recipient:string; }[]; totalAmount:string; affiliateAmount:string; affiliateCode?:string; affiliatePublicKey?:string; currency: { id:string; blockchain?: { engine:BlockchainEngine } |null; }; transactionType?:TransactionType; tokenQuote?:TokenQuoteMeta; transactionStatus:TransactionStatus// e.g. 'SUCCESS'}// used for converting between pricing currency (from) and what they paid with (to)// note: from could be a crypto currency (e.g. (0.1 ETH), or fiat currency (e.g. $5)// to is always going to be a crypto currency.// This is useful when using swaps, to see what they paidclassTokenQuoteMeta { from:string; fromAmountDecimal:string; to:string; toAmountMinimal:string;}classBlockchainEngine { id:string; type:BlockchainEngineType;}enumPaymentRequestType { PAYLINK ="PAYLINK", PAYSTREAM ="PAYSTREAM",}enumPaylinkEvents { CREATED ="CREATED",}enumTransactionType { REFUND ="REFUND", PAYLINK ="PAYLINK",}enumBlockchainEngineType { EVM ="EVM", SOL ="SOL", BTC ="BTC",}
Note: When you create or list Pay Link webhooks, a sharedToken is generated. This token is sent to your endpoint as authorization: Bearer SHARED_TOKEN to validate that the webhook originates from Helio.
Listing Pay Link Webhooks
You can list all the hooks that are registered for a Pay Link with the following curl request:
This will return an array of all Webhooks that are registered for the Pay Link. In case the API key isn't associated with Pay Link, an unauthorised request will be thrown.
[ {"id":"636a3838591b00789e778b79","creator": undefined,// for legacy webhooks"paylink":"636501dad706741f1ad63779","company":"6343e77d91c393456aa56422","targetUrl":"https://targetUrl.com","events": ["CREATED" ]"sharedToken": "1HSY3MM4I1hvIRp2xv83uTY3J55nIE66vuaBrutBoCCr3fChi8rY458" }]
Deleting Pay Link Webhook
You can delete any Webhook ID by calling the delete endpoint:
To be clear, in this example, 636a75ee5a9078bb9803a681is the ID of the Webhook. You can get this when you create a webhook, or by listing all webhooks for a Pay Link
Pay Stream examples
Pay Streams are recurring payments, great for subscriptions or gated content. For streamId 636a74162e72d4ad24ac9ce9, a similar curl command can be used to register recurring payment webhooks. The POST request is sent to targetUrl: https://target-url.com/post-endpoint.
This will return an array of all Webhooks that are registered for the Pay Stream. In case the API key isn't associated with stream, an unauthorised request error will be thrown.