Invincible Pay
Manual etransfers

Introduction

Recommended Integration Model

For manual eTransfer payments, your merchant website can use either:

  1. Webhooks — recommended
  2. Polling — fallback option

Webhooks are better because your system is notified when InvinciblePay has an update, instead of repeatedly checking for pending eTransfers.

Manual eTransfer Payment Flow with Webhooks

  1. Customer starts checkout on your website.
  2. Your backend creates an internal order.
  3. Your website shows the customer manual eTransfer instructions.
  4. Customer sends an Interac e-Transfer to your InvinciblePay receiving email.
  5. InvinciblePay detects the incoming manual eTransfer.
  6. InvinciblePay sends a webhook to your server.
  7. Your backend uses the webhook data to find the matching order.
  8. Your backend calls the manual eTransfer claim endpoint with the security answer.
  9. If the claim succeeds, your backend marks the order as paid.

Step 1: Register Your Webhook URL

Register a URL to receive webhook notifications:

POST /v1/webhook-urls

Example body:

{
  "url": "https://myfencestore.com/api/invinciblepay/webhook"
}

You can also list your registered webhook URLs:

GET /v1/webhook-urls

And manage an existing webhook URL:

PUT /v1/webhook-urls/{uuid}
DELETE /v1/webhook-urls/{uuid}

The API also exposes a webhook history/list endpoint at /v1/webhooks.

Step 2: Get Your Manual eTransfer Receiving Email

GET /v1/manual-etransfers/address

This returns the email address customers should send eTransfers to — the manual eTransfer receiving address that can be shared to receive eTransfers that must later be accepted manually.

Step 3: Show Payment Instructions to the Customer

Example:

Send an Interac e-Transfer for exactly $125.00 CAD to:
merchant123@cadpayment.ca

Security question:
What is the Payment ID for your ORD-10045 order?

Security answer:
PID-000985

Important: send the exact amount.

Store this in your order:

order_id
expected_amount
security_answer
payment_status = pending
manual_etransfer_id = null
interac_reference_number = null

Step 4: Receive Webhook on Your Website

Your webhook endpoint should be:

POST /api/invinciblepay/webhook

Example backend logic:

  • Receive the webhook.
  • Store the raw webhook body.
  • If the webhook was already processed, return 200.
  • Identify the manual eTransfer id or related transaction id.
  • Fetch the latest manual eTransfer data from InvinciblePay.
  • Match it to your order.
  • If matched, claim the manual eTransfer.
  • If the claim succeeds, mark the order as paid.
  • Return 200.

Do not rely only on the webhook body to mark an order paid. Use the webhook as a notification, then fetch/confirm the latest state from the API.

Step 5: Claim the Manual eTransfer

POST /v1/manual-etransfers/{id}/claim

Body:

{
  "securityAnswer": "ORD-10045"
}

The claim endpoint requires a security answer. The transaction appears in the transaction list shortly after claiming.

After success:

payment_status = paid
manual_etransfer_id = met_123
paid_at = now()

Polling Fallback

Even with webhooks, run a backup polling job every few minutes:

GET /v1/manual-etransfers?status=pending&pageSize=20&page=0&sort=desc

Use this to catch missed webhook deliveries.

Important Rules

  • Never expose your InvinciblePay API key in frontend code.
  • Always process webhooks on your backend.
  • Always make webhook handling idempotent.
  • Store the raw webhook payload for debugging.
  • Return HTTP 200 only after your server accepts the webhook.
  • Use exact amount matching.
  • Do not mark the order paid just because a webhook arrived.
  • Mark the order paid only after successful claim or confirmed completed status.
  • Use polling as a backup safety net.

On this page