# Payment Webhook and Razorpay

> Stop Edesy Collect reminders automatically when a debtor pays - call POST /v1/collect/webhooks/payment from your backend, for example from your Razorpay payment webhook handler. Also how Razorpay auto-pay bills your Collect plan.

Source: https://edesy.in/docs/collect/payments/payment-webhook-razorpay

The Collect payment webhook is an endpoint your own backend calls when a debtor pays: `POST /v1/collect/webhooks/payment` with the debtor's contact ID. Collect marks them paid and cancels their remaining calls. If you collect payments with Razorpay, forward each successful payment from your Razorpay webhook handler to this endpoint.

Razorpay is used in two separate places in Collect:

| What | Who receives Razorpay's events |
|---|---|
| Paying for your Collect plan (auto-pay subscription) | Edesy, automatically. Nothing to set up. |
| Your debtors paying you | Your backend, from your own Razorpay account. You then call the Collect payment webhook. |

## The payment webhook

```
POST https://voice-api.edesy.in/v1/collect/webhooks/payment
```

Authenticate with your API key like any other Collect call.

| Field | Required | Description |
|---|---|---|
| `contact_id` | Yes | The debtor's contact `id` |
| `status` | No | `paid` (default), `promised`, `stopped` or `pending` |

```bash
curl -X POST https://voice-api.edesy.in/v1/collect/webhooks/payment \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"contact_id": "CONTACT_ID", "status": "paid"}'
```

```json
{ "status": "ok" }
```

The call is idempotent: sending `paid` twice for the same debtor is safe. An unknown or foreign `contact_id` returns `404`, and an invalid status returns `400`.

## Wire it to your Razorpay account

1. **Keep the mapping.** When you upload debtors, list the campaign contacts (`GET /v1/campaigns/:id/contacts`) and store each debtor's Collect `id` next to your own loan or invoice record.
2. **Put your reference on the payment.** When you create a Razorpay payment link or order for a debtor, add your loan or invoice reference in its notes.
3. **Handle Razorpay's payment event** in your backend as you do today, and verify Razorpay's signature.
4. **Look up the Collect contact ID** from the reference in the notes.
5. **Call the Collect payment webhook** with that `contact_id` and `"status": "paid"`.

```js
// Inside your existing Razorpay webhook handler, after verifying Razorpay's signature
const ref = payload.payment.entity.notes.loan_ref;       // your reference
const contactId = await lookupCollectContactId(ref);     // your mapping
if (contactId) {
  await fetch("https://voice-api.edesy.in/v1/collect/webhooks/payment", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.EDESY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contact_id: contactId, status: "paid" }),
  });
}
```

The same pattern works with any payment gateway, bank feed or loan system that can tell your backend a payment arrived.

## How your Collect plan uses Razorpay

When you subscribe on the Plans page, Razorpay checkout opens to set up auto-pay. Edesy receives Razorpay's subscription events directly, activates your plan once the first charge succeeds, and credits your plan fee to your wallet each month. See [Plans and Pricing](https://edesy.in/docs/collect/getting-started/plans-and-pricing).

## FAQ

**Does Collect connect to my Razorpay account directly?**
No. Your backend receives your Razorpay events and calls the Collect payment webhook.

**Can I send a phone number instead of a contact ID?**
No. The webhook takes the contact `id`.

**What if the payment arrives during a call?**
That call finishes; no further calls are made.

**Can I use it for partial payments?**
Send `promised` or leave the debtor `pending`, depending on your policy. Collect does not track amounts paid.
