# AquaPay H2H Integration Guide

This guide is for merchants who want a hosted-checkout integration similar to Razorpay or PayU payment-link flows, while still being able to surface AquaPay deeplinks and app buttons inside their own payment page when available.

## Overview

Default H2H hosted-intent flow:

1. Merchant backend signs and sends `POST /api/payments/h2h/create-order`
2. AquaPay returns `payment_url` / `checkout_url`
3. AquaPay may also return `deeplink`, `intentURIData`, `appLinks`, and `qr` if PayU responded quickly enough
4. Merchant either opens the AquaPay hosted checkout or renders the deeplink and app buttons on its own payment page
5. Customer completes payment in a UPI app
6. AquaPay receives PayU updates and forwards the final status to the merchant webhook
7. Merchant also verifies status with `GET /api/payments/h2h/status/:merchantOrderId`

## Authentication

Every H2H API request must include:

- `X-API-Key`
- `X-Timestamp`
- `X-Signature`

The signing format is the same as the standard merchant API.

## Create Hosted Checkout Order

Endpoint:

```text
POST /api/payments/h2h/create-order
```

Backward-compatible aliases:

```text
POST /api/payments/create-order
POST /api/create-payment
```

Recommended request for hosted deeplink H2H:

```json
{
  "merchant_id": "mrc_xxxxxxxx",
  "integrationType": "h2h",
  "order_id": "ORD-H2H-10001",
  "amount": "5000.00",
  "currency": "INR",
  "callback_url_success": "https://merchant.example.com/webhooks/aquapay-success",
  "callback_url_failure": "https://merchant.example.com/webhooks/aquapay-failure",
  "return_url": "https://merchant.example.com/payments/return",
  "customer": {
    "name": "Rahul Sharma",
    "email": "rahul@example.com",
    "phone": "9999999999"
  }
}
```

Notes:

- For the normal hosted deeplink checkout, omit `paymentMethod`. AquaPay uses the hosted intent flow internally.
- Use `paymentMethod: "upi_qr"` only if you specifically want a hosted QR-first flow.
- Use `paymentMethod: "upi_collect"` only if you specifically want a collect request flow.
- `return_url` or success/failure return URLs should be provided for H2H
- `Idempotency-Key` is strongly recommended

Example response:

```json
{
  "ok": true,
  "accepted": true,
  "integrationType": "h2h",
  "redirectRequired": true,
  "customerAction": "redirect_to_checkout",
  "orderId": "PAY20260323143000AB12CD34",
  "merchantOrderId": "ORD-H2H-10001",
  "payment_url": "https://payments.aquapay.online/s/aqp123xy",
  "checkout_url": "https://payments.aquapay.online/s/aqp123xy",
  "payment_url_long": "https://payments.aquapay.online/paynow/?orderId=...",
  "status": "pending",
  "providerDispatchState": "succeeded",
  "checkoutState": "pending",
  "intentURIData": "pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent",
  "deeplink": "upi://pay?pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent",
  "appLinks": {
    "generic": "upi://pay?pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent",
    "gpay": "gpay://upi/pay?pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent",
    "phonepe": "phonepe://upi/pay?pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent",
    "paytm": "paytm://upi/pay?pa=merchant@upi&pn=Merchant&tr=ABC123&tid=PAY20260323143000AB12CD34&am=5000.00&cu=INR&tn=UPIIntent"
  }
}
```

Merchant action:

- Primary H2H path: redirect the customer to `payment_url` or `checkout_url`
- Merchant-hosted payment page path: if `deeplink` or `appLinks` are present, show app buttons on your own page and open the selected link
- If `deeplink` is blank immediately after create-order, poll the H2H status API until `deeplink` / `appLinks` appear, or let the AquaPay hosted checkout render them

## Check Hosted Checkout Status

Endpoint:

```text
GET /api/payments/h2h/status/:merchantOrderId
```

Example response fields:

- `status`
- `payment_status`
- `integration_type`
- `redirect_required`
- `provider_dispatch_state`
- `payment_url`
- `intent_uri_data`
- `deeplink`
- `app_links`
- `qr`
- `last_payu_webhook_at`
- `last_merchant_webhook_at`

## Merchant-Hosted Payment Page

If you want to keep the customer on your own payment page while still using the H2H create-order contract, do this:

1. Call `POST /api/payments/h2h/create-order`
2. Render your own payment page immediately
3. If the create response already contains `deeplink` or `appLinks`, show UPI app buttons right away
4. If the deeplink fields are empty, poll `GET /api/payments/h2h/status/:merchantOrderId`
5. As soon as `deeplink` / `app_links` are returned, show `Open GPay`, `Open PhonePe`, `Open Paytm`, or `Open Any UPI App`
6. Continue using merchant webhooks plus status polling for final-state confirmation

This lets you use AquaPay as the H2H gateway while still presenting the payment step inside your own website.

## Merchant Webhooks

AquaPay sends terminal payin webhooks to:

- `callback_url_success`
- `callback_url_failure`

Headers:

- `X-ABC-Signature`
- `X-ABC-Event`
- `X-ABC-Source`
- `X-ABC-Attempt`

Best practices:

1. Treat webhook delivery as the primary final-state signal.
2. Use `GET /api/payments/h2h/status/:merchantOrderId` as fallback or for manual verification.
3. Handle duplicate webhook deliveries idempotently.
4. Never mark success unless AquaPay says the final status is `success`.
