old_Loopcrypto.xyz
  • Introduction
  • Supported networks and tokens
  • Loop + Frames
  • Learn
    • How Loop works
    • Core components
      • Collecting authorization
        • Enabling payment on multiple networks
        • Accepting ETH and MATIC
      • Sending payment requests
      • Checking a customer's balance & allowance
      • Receipts and reminders
      • Customer portal
    • Loop + your financial stack
      • Linking on-chain transactions with invoices in your ERP system
      • Connecting with accounting software
      • Crypto off-ramp
    • Case studies
  • Dashboard functionality
    • Subscriptions
      • Free trials, discounts and more
      • Auto-invoicing
      • Auto-cancelations
    • One-time payments
    • Scheduling outbound payments
      • Internal notes
    • Editing an upcoming payment
    • Payments for platforms
  • Integrations
    • Stripe + Loop
      • Getting setup
      • Stripe Connect setup
      • Subscriptions
        • Free trials
        • Upgrading a customer or editing a subscription's products
      • Invoicing
      • One-time payments
      • Coupon codes
      • Stripe Connect - Subscriptions
      • FAQs about Stripe integration
    • Chargebee + Loop
      • Getting setup
      • Subscriptions
      • One-time payments
      • Coupon codes
    • Quickbooks + Loop
      • Invoicing
    • Xero + Loop
      • Invoicing
    • Ghost.org + Loop
    • Zapier + Loop
    • Manually add integrations
  • Technical Docs
    • APIs
      • Entity
        • Adding child entities
        • Adding user to child entity
        • Get child entities
      • Items
        • Adding items
          • Item types
          • Categories
        • Retrieving an item
        • Updating an item
        • Deactivating an item
      • Agreements
      • Transfer requests
        • Signing transfer requests
        • Loop CLI
        • Canceling transfer requests
        • Transfer request status
        • Handling unfulfilled transfer requests
        • Validations
      • Webhooks
        • Checking webhook signatures
        • Demo App
        • Slack, Airtable, Discord, Telegram
    • Archeticture
      • Smart contract
        • Deploying your smart contract
          • Modifying smart contract properties
      • Collecting authorization
        • Checkout page
          • Additional functionality
          • Add "pay with crypto" button
        • Checkout widget
          • NPM package readme
        • Checkout parameter examples
      • Providing on-chain payment based access
        • Subscription gated communities
    • Loop SDK
      • Verify Webhook
      • Transfers
      • Error Handling
      • Generating API keys
    • Sample guide: Collect a subscription or one-time payment
    • Integrating the Loop Protocol into your dApp
      • Payroll applications
      • Loan platforms (credit cards, BNPL)
    • Security
      • API Authentication
      • Securing with signatures
      • API Trust assumptions
      • Audits
  • FAQs
  • Company Dashboard
  • Loop Portal
Powered by GitBook
On this page
  • Webhook timeline examples
  • ScheduledAgreementCancel
  • AgreementCancelled
  • TransferCreated
  • TransferFinalized
  • TransferProcessed
  • Late payment
  1. Technical Docs
  2. APIs

Webhooks

PreviousValidationsNextChecking webhook signatures

Last updated 9 months ago

Webhooks make integration with Loop easy by allowing you to subscribe to certain events that Loop emits. Loop will automatically create an account for you when deploying your contract so that you will be able to subscribe to webhook events. The shared secret for the account will be provided along with the contract address.

After your Loop account is set up, you will be able to subscribe to these events and configure an endpoint, which will receive a notification each time the event occurs.

If you'd like to receive webhooks, please send us an endpoint where we can POST data to. These are the webhook events currently available. See below for field details and example payloads.

  • AgreementSignedUp

  • ScheduledAgreementCancel

  • AgreementCancelled

  • TransferCreated

  • TransferFinalized

  • TransferProcessed

  • LatePayment

Webhook retry logic

Loop has a standard retry cadence if a webhook is not successfully ingested. Loop will retry 3 times immediately and then start to back off over the next ~20 seconds. There are about 15 retries within this period. After that, if Loop still receives a failure message from your endpoint, retries are attempted every 20 seconds.

Webhook timeline examples

AgreementSignedUp

Fields:

Field
Type
Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network (e.g., Ethereum, Goerli, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

subscriber

address

The wallet address that subscribed

item

string

The name of the item subscribed to

itemId

string

The ID of the item

agreementId

string

The ID of the agreement

agreementAmount

string

The amount for the subscription in USD

frequencyNumber

number

The frequency that the subscription repeats

frequencyUnit

string

The frequency unit - minutes, hours, days, weeks, years

addOnAgreements

string

A comma delimited string of additional agreement IDs

addOnItemIds

string

A comma delimited string of additional item IDs

addOnTotalAmount

string

The total amount for the add on items

paymentTokenSymbol

string

The symbol of the token used to pay for the subscription

eventDate

number

The date the event occurred - Unix time in seconds

refId

string

A custom reference ID that is stored and returned via "SignedUp" and "Cancelled" webhooks

metadata

string

JSON object as a string. Possible key value pairs:

Example Payload:

{
      "event": "AgreementSignedUp",
      "transaction": "-",
      "networkId": 5,
      "networkName": "Goerli",
      "contractAddress": "0x9876543210C511D91Ad0F18D1Dd12987654321",
      "email": "example@mail.com",
      "company": "Test Company",
      "parent": "-",
      "subscriber": "0x9E76932D7661C976a630aB9d06E45c0dc510A4b1",
      "item": "My Subscription",
      "itemId": "eb39844c-b5c7-4a42-a595-259e0fd9e6e2",
      "agreementId": "43bc9a0b-86b1-4a0a-8340-aef5585e2cd5",
      "agreementAmount": "10.00",
      "frequencyNumber": 1,
      "frequencyUnit": "Month",
      "addOnAgreements": "",
      "addOnItems": "",
      "addOnItemIds": "",
      "addOnTotalAmount": "0.00",
      "paymentTokenSymbol": "USDC",
      "paymentTokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "eventDate": 1701451658,
      "refId": "my-ref-id",
      "metadata": "{ \"trialDays\": 5 }"
}

ScheduledAgreementCancel

Fields:

Field
Type
Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network (e.g., Ethereum, Goerli, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

entityId

string

The ID of the entity

agreementId

string

The agreement ID that was canceled

subscriber

string

The user's wallet address

agreementStartDate

number

The start date of the agreement - Unix time in seconds

eventDate

number

The date the subscription was canceled - Unix time in seconds

itemId

string

The ID of the item

itemName

string

The name of the item

refId

string

The reference ID passed in from checkout

cancellationEffectiveDate

number

The date the subscription will be cancelled. Unix time in seconds.

cancellationReason

string

Optional. Reason given for cancellation. May be system generated as well.

The cancellationReason field can have the following values:

  • “Cancelled by Stripe” - Loop received a cancellation notification from Stripe and then emitted the "ScheduledAgreementCancel" event. This will occur when a subscription is cancelled in Stripe.

  • “Canceled due to uncollectible payment” - If the product is canceled via Loop's auto-cancel feature.

Example Payload:

{
      "event": "ScheduledAgreementCancel",
      "transaction": "-",
      "networkId": 31337,
      "networkName": "local",
      "contractAddress": "0xfb255E7d519872D8E9E7BE8C79CE4b98444209Ce",
      "email": "-",
      "company": "Coin Currency LLC 94 48a916fe-c881-49aa-922e-53265185a11a (79faed4d-6606-455f-a8d8-d358c001d617)",
      "parent": "-",
      "entityId": "79faed4d-6606-455f-a8d8-d358c001d617",
      "agreementId": "43bc9a0b-86b1-4a0a-8340-aef5585e2cd5",
      "subscriber": "0x9E76932D7661C976a630aB9d06E45c0dc510A4b1",
      "agreementStartDate": 1701457297,
      "eventDate": 1701457297,
      "itemId": "eb39844c-b5c7-4a42-a595-259e0fd9e6e2",
      "itemName": "My Subscription",
      "refId": "my-customer-ref",
      "cancellationEffectiveDate": 1704067297,
      "cancellationReason": "No longer need product"
}

AgreementCancelled

Fields:

Field
Type
Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network (e.g., Ethereum, Goerli, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

entityId

string

The ID of the entity

agreementId

string

The agreement ID that was canceled

subscriber

string

The user's wallet address

agreementStartDate

number

The start date of the agreement - Unix time in seconds

eventDate

number

The date the subscription was canceled - Unix time in seconds

itemId

string

The ID of the item

itemName

string

The name of the item

refId

string

The reference ID passed in from checkout

cancellationReason

string

Optional. Reason given for cancellation. May be system generated as well.

Example Payload:

{
      "event": "AgreementCancelled",
      "transaction": "-",
      "networkId": 31337,
      "networkName": "local",
      "contractAddress": "0xfb255E7d519872D8E9E7BE8C79CE4b98444209Ce",
      "email": "-",
      "company": "Coin Currency LLC 94 48a916fe-c881-49aa-922e-53265185a11a (79faed4d-6606-455f-a8d8-d358c001d617)",
      "parent": "-",
      "entityId": "79faed4d-6606-455f-a8d8-d358c001d617",
      "agreementId": "43bc9a0b-86b1-4a0a-8340-aef5585e2cd5",
      "subscriber": "0x9E76932D7661C976a630aB9d06E45c0dc510A4b1",
      "agreementStartDate": 1701457297,
      "eventDate": 1701457297,
      "itemId": "eb39844c-b5c7-4a42-a595-259e0fd9e6e2",
      "itemName": "My Subscription",
      "refId": "my-customer-ref",
      "cancellationReason": "No longer need product"
}

TransferCreated

This webhook is sent whenever a transfer request is created. This includes, transfer requested autogenerated by Loop as well as drafts created by Stripe.

Field

Type

Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network the event occurred on (e.g., Ethereum, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

id

string

The ID of the transfer

invoiceId

string

The ID of the invoice

billDate

number

The due date of the payment - Unix time in seconds

toAddress

string

The wallet address the funds will go to

fromAddress

string

The wallet of the user

tokenSymbol

string

Symbol of the token, e.g: USDC

tokenAddress

string

The address of the payment token

paymentType

string

Either Transaction or Fee

usd

boolean

Flag to indicate if the transfer is priced in USD or not

amount

string

The transfer amount

item

string

The name of the item

itemId

string

The ID of the item

source

string

The source of the transfer. Can be Manual, Autogenerated, Stripe, Chargebee, QuickBooks or Xero

batchId

string

The batch id of the transfer

transferId

string

The internal ID of the transfer

refId

string

A custom reference ID that is stored and returned via "SignedUp" and "Cancelled" webhooks

agreementId

string

The ID of the agreement

Example Payload:

{
      "event": "TransferCreated",
      "transaction": "-",
      "networkId": 5,
      "networkName": "Goerli",
      "contractAddress": "0xfb255E7d519872D8E9E7BE8C79CE4b98444209Ce",
      "email": "example@mail.com",
      "company": "Test Company (72575f32-c90c-458b-879a-eb1f50438258)",
      "parent": "-",
      "id": "ee324368-8015-4c8a-a80b-3458bbc110c0",
      "invoiceId": "INV-01",
      "billDate": 1689890089,
      "toAddress": "0x38487e6147928c014a749795a04b67ccc95efe61",
      "fromAddress": "0x19dfdc194Bb5CF599af78B1967dbb3783c590720",
      "tokenSymbol": "USDC",
      "tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "paymentType": "Transaction",
      "usd": true,
      "amount": "29.10",
      "item": "Item 1",
      "itemId": 1,
      "source": "Manual",
      "batchId": "4a81e3d5-ee71-40c1-90b6-2edcef131841",
      "transferId": "97e412c6-cd7b-4d82-a1f1-4f9e7a4c2d3e",
      "refId": "my-customer-ref",
      "agreementId": "43bc9a0b-86b1-4a0a-8340-aef5585e2cd5"
}

TransferFinalized

When a draft invoice is finalized in Stripe, we will send you a webhook. Unless you explicitly disable it, invoices you create in Stripe ​automatically finalize about 1 hour before the payment is due. Invoices you create with the Stripe API, however, ​​won’t automatically finalize.

Field

Type

Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network the event occurred on (e.g., Ethereum, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

id

string

The ID of the transfer

invoiceId

string

The ID of the invoice

billDate

number

The due date of the payment - Unix time in seconds

toAddress

string

The wallet address the funds will go to

fromAddress

string

The wallet of the user

tokenSymbol

string

Symbol of the token, e.g: USDC

tokenAddress

string

The address of the payment token

paymentType

string

Either Transaction or Fee

usd

boolean

Flag to indicate if the transfer is priced in USD or not

amount

string

The transfer amount

item

string

The name of the item

itemId

string

The ID of the item

source

string

The source of the transfer. Can be Manual, Autogenerated, Stripe, Chargebee, QuickBooks or Xero

batchId

string

The batch id of the transfer

{
      "event": "TransferFinalized",
      "transaction": "-",
      "networkId": 5,
      "networkName": "Goerli",
      "contractAddress": "0xfb255E7d519872D8E9E7BE8C79CE4b98444209Ce",
      "email": "example@mail.com",
      "company": "Test Company (72575f32-c90c-458b-879a-eb1f50438258)",
      "parent": "-",
      "id": "ee324368-8015-4c8a-a80b-3458bbc110c0",
      "invoiceId": "INV-01",
      "billDate": 1689890089,
      "toAddress": "0x38487e6147928c014a749795a04b67ccc95efe61",
      "fromAddress": "0x19dfdc194Bb5CF599af78B1967dbb3783c590720",
      "tokenSymbol": "USDC",
      "tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "paymentType": "Transaction",
      "usd": true,
      "amount": "29.10",
      "item": "Item 1",
      "itemId": 1,
      "source": "Stripe",
      "batchId": "4a81e3d5-ee71-40c1-90b6-2edcef131841"
}

TransferProcessed

Field

Type

Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network (e.g., Ethereum, Goerli, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

transferId

string

The internal ID of the transfer

success

boolean

Indicates if the process was processed successfully

paymentTokenAddress

string

The address of the payment token

paymentTokenSymbol

string

The symbol of the token address (e.g., USDC)

endUser

string

The wallet of the user

reason

string

If the transfer failed, this field will explain why

invoiceId

string

The invoice ID

amountPaid

number

The amount paid in the transfer

agreementId

string

The Loop agreement ID associated with the transfer

refId

string

The reference number for the transfer

batchId

string

The batch ID of the transfer

usdAmount

string

US dollar amount of the transfer request

Example payload

{
    "event": "TransferProcessed",
    "transaction": "0x3210f2e709a75df98181178401fd44c074f49e155a9e8627aa0866b870465dec",
    "networkId": 5,
    "networkName": "Goerli",
    "contractAddress": "0x9876543210C511D91Ad0F18D1Dd12987654321",
    "email": "example@mail.com",
    "company": "SubCompany Inc",
    "parent": "Company Inc",
    "transferId": "97e412c6-cd7b-4d82-a1f1-4f9e7a4c2d3e",
    "success": true,
    "paymentTokenAddress": "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
    "paymentTokenSymbol": "USDC",
    "endUser": "0x84d455d0b1ffb0b488cbd1f4b098f076e5628065",
    "reason": "",
    "invoiceId": "inv_0MNiLT0NXI7Xajf6fcW8PmCPpE",
    "amountPaid": 1.423,
    "agreementId": "4684326b-aed2-49cb-a60a-fcc8e9cdc8e3",
    "refId": "customer-123",
    "batchId": "68934968-3260-4c37-9ee7-c93c2efa4f84",
    "usdAmount": "$1.40"
{

Late payment

Late payment notifications will be sent 10 minutes after the due date for the Transfer Request. If the Transfer Request is processed within that 10 minute window, no late payment notification will be sent.

Field

Type

Description

event

string

The name of the event

transaction

string

Will always be blank since there is no onchain transaction

networkId

number

The ID of the network the event occurred on - 1, 5, 137, 80001 etc

networkName

string

The name of the network the event occurred on (e.g., Ethereum, Polygon, etc.)

contractAddress

address

The address of the contract the event occurred in

email

string

The email address of the subscriber (if any)

company

string

Your company name

parent

string

The name of the parent company (if any)

subscriber

address

The wallet address that the payment relates to

dueDate

number

The date the transfer request is due - Unix time in seconds

amountDue

number

The amount that was due that hasn't been paid

lateReason

string

The reason the payment is late ("Insufficient balance" and/or "Insufficient allowance"

eventDate

number

The date the event occurred - Unix time in seconds

refId

string

The reference number for the transfer

agreementId

string

The Loop agreement ID associated with the transfer

transferId

string

The internal ID of the transfer

invoiceId

string

The invoice ID

Example payload

{
	event: "LatePayment",
	transaction: "0xeec977f21bfa8fd084696fa624fa22bcf46b2b5236207c2924f755bc2c3bdf60",
	networkId: 5,
	networkName: "goerli",
	contractAddress: "0xeF265A078Be7854A7e9e1f9d36c40f61Fad7f8b8",
	email: "name@email.com",
	company: "My Company",
	subscriber: "0x1f9090aaE28b8a3dCeaDf281B0F12828e676c326",
	dueDate: 1683390682,
	amountDue: 100000000;
	lateReason: "Insufficient allowance.",
	eventDate: 1683563482
	agreementId: "4684326b-aed2-49cb-a60a-fcc8e9cdc8e3",
    	refId: "customer-123",
    	transferId: "97e412c6-cd7b-4d82-a1f1-4f9e7a4c2d3e",
	invoiceId: "inv_0MNiLT0NXI7Xajf6fcW8PmCPpE"	
}