# WhatsApp Agent — Order Creation & Fiuu Payment Link Integration

> **Superseded for cart/order creation.** This doc originally specified guest
> checkout (`/V1/guest-carts/*`). The actual bot (`magento_order.py`) uses
> **customer carts with an admin/integration token** instead, since orders must
> attach to existing Magento customers. See `docs/whatsapp-agent-magento-side-answers.md`
> for the confirmed customer-cart call sequence and why guest checkout doesn't
> apply here. Sections 5–9 below (payment link behavior, admin setup, security)
> are still accurate — only the cart-creation steps (§5.1–5.4 style guest calls)
> are outdated.

Integration guide for the external WhatsApp bot to create Magento orders and obtain a Fiuu (RazerPay) payment link. Written for whoever (human or Claude) is updating the bot's Python code.

**Audience:** Bot / integration developer
**Related code:** `app/code/RazerPay/PaymentAgent`, `app/code/RazerPay/Payment`
**Last updated:** 2026-08-04

---

## 1. Summary

The bot creates a guest order via Magento's standard core REST checkout endpoints, using the payment method code `razerpay_payment_agent` instead of a real payment form. It then calls one custom Magento endpoint to get back a payment link URL, and sends that URL to the customer over WhatsApp. Magento does nothing WhatsApp-related — the bot owns delivery.

Two different auth modes are involved:
- Steps 1–4 (cart/order creation) use Magento's **anonymous guest-checkout endpoints** — no token needed.
- Step 5 (payment link lookup) requires an **OAuth Integration access token** — see [Section 3](#3-authentication).

---

## 2. Prerequisites (Magento admin side — should already be done before the bot is updated)

- [ ] Module `RazerPay_PaymentAgent` enabled (`bin/magento module:enable RazerPay_PaymentAgent`, `setup:upgrade`, `di:compile`, `cache:flush`).
- [ ] Payment method enabled: **Stores > Configuration > Sales > Payment Methods > Fiuu Payment Link (Agent) > Enabled = Yes**.
- [ ] A Magento **Integration** created (System > Integrations) scoped to resource `RazerPay_PaymentAgent::payment_link` (optionally also `Magento_Sales::actions_view` if the bot needs to poll order status). Access token copied into the bot's secret store.
- [ ] Confirm the store's Fiuu channel codes to use (same list as configured under **Razer Merchant Services > Channels**), since `channel_code` must be one of these.

If any of the above isn't done yet, the calls below will fail — check with the Magento side first.

---

## 3. Authentication

| Step | Endpoint type | Auth |
|---|---|---|
| Cart/order creation (steps 1–4) | Guest checkout REST | None (`Authorization` header omitted) |
| Payment link lookup (step 5) | Custom REST | `Authorization: Bearer <integration_access_token>` |

Store the integration token as a bot secret (env var / secrets manager), never hardcoded.

---

## 4. Base URL

```
https://<magento-store-domain>/rest/V1
```

Use the store's actual REST base (check `default` store view unless multi-store routing is needed).

---

## 5. Call sequence

### Step 1 — Create guest cart

```http
POST /rest/V1/guest-carts
```
No body. Response is a plain string `cartId` (e.g. `"a1b2c3d4e5f6g7h8i9j0"`).

### Step 2 — Add item(s)

```http
POST /rest/V1/guest-carts/{cartId}/items
Content-Type: application/json

{
  "cartItem": {
    "sku": "PRAWN-001",
    "qty": 2,
    "quote_id": "{cartId}"
  }
}
```
Repeat per line item.

### Step 3 — Set shipping information (skip only if the store is 100% virtual/digital)

```http
POST /rest/V1/guest-carts/{cartId}/shipping-information
Content-Type: application/json

{
  "addressInformation": {
    "shipping_address": {
      "region": "Selangor",
      "country_id": "MY",
      "street": ["123 Jalan Example"],
      "telephone": "0123456789",
      "postcode": "40000",
      "city": "Shah Alam",
      "firstname": "Customer",
      "lastname": "Name",
      "email": "customer@example.com"
    },
    "billing_address": {
      "region": "Selangor",
      "country_id": "MY",
      "street": ["123 Jalan Example"],
      "telephone": "0123456789",
      "postcode": "40000",
      "city": "Shah Alam",
      "firstname": "Customer",
      "lastname": "Name",
      "email": "customer@example.com"
    },
    "shipping_method_code": "flatrate",
    "shipping_carrier_code": "flatrate"
  }
}
```
Adjust carrier/method codes to whatever shipping methods the store actually has enabled.

### Step 4 — Set payment method and place order

```http
POST /rest/V1/guest-carts/{cartId}/payment-information
Content-Type: application/json

{
  "email": "customer@example.com",
  "paymentMethod": {
    "method": "razerpay_payment_agent",
    "additional_data": {
      "channel_code": "FPX_MB2U"
    }
  },
  "billingAddress": {
    "region": "Selangor",
    "country_id": "MY",
    "street": ["123 Jalan Example"],
    "telephone": "0123456789",
    "postcode": "40000",
    "city": "Shah Alam",
    "firstname": "Customer",
    "lastname": "Name",
    "email": "customer@example.com"
  }
}
```

**Important:**
- `paymentMethod.method` must be exactly `razerpay_payment_agent` (this is the new method, not `razerpay_payment`).
- `additional_data.channel_code` must be a valid Fiuu channel code configured on the store (ask the Magento admin for the current list — common ones: `FPX_MB2U` for FPX Maybank2u, `CC` for credit/debit card, `DuitNow_QR` for DuitNow QR — confirm exact values against the store's config, do not assume).
- **Response is an integer** — the order's `entity_id` (e.g. `482`). This is NOT the increment id (`"000000482"`-style). Keep it — it's required for step 5.

### Step 5 — Get the Fiuu payment link

```http
GET /rest/V1/razerpay-payment-agent/orders/{orderId}/payment-link
Authorization: Bearer <integration_access_token>
```
`{orderId}` = the integer `entity_id` from step 4's response.

Response:
```json
{
  "url": "https://<store>/razerpay_payment_agent/order/pay?order_id=000000482&token=9f8e7d6c5b4a3f2e1d0c...",
  "order_increment_id": "000000482"
}
```

Send `url` to the customer over WhatsApp. That's the whole integration — Magento's job ends here.

---

## 6. What the customer experiences when they open the link

Opening `url` renders a plain HTML page that auto-submits a POST form to Fiuu's hosted payment page (no login, no session needed — works from any device, e.g. opened from WhatsApp on a phone that never talked to Magento before). Customer completes payment on Fiuu's page; Fiuu calls back to Magento server-to-server to mark the order paid — no further bot involvement needed. Bot does not need to poll for payment confirmation unless it wants to proactively follow up (optional, would need `Magento_Sales::actions_view` scope and `GET /V1/orders/{id}` to check `status`).

---

## 7. Error handling the bot must account for

| Scenario | What happens | Bot handling |
|---|---|---|
| `channel_code` invalid/unsupported | Step 4 order still places, but step 5's underlying link builder will fail silently server-side and the link page will 404 for the customer | Validate `channel_code` against the known channel list before sending; log/alert if the store's channel list changes |
| Cart/address/payment REST call returns 4xx | Standard Magento REST error JSON (`{"message": "..."}`) | Surface the message, do not retry blindly — likely a data problem (bad SKU, missing address field) |
| Step 5 called with wrong/mismatched `orderId` | `404` with `NoSuchEntityException` message | Means order wasn't placed with `razerpay_payment_agent` or doesn't exist — check step 4's response was captured correctly |
| Step 5 integration token expired/revoked | `401 Unauthorized` | Refresh/rotate the token; alert the admin |
| Customer never opens the link / never pays | Order sits in `pending_payment`, auto-cancelled by a Magento cron after the store's configured expiry window (shared with the regular checkout flow's expiry setting) | No bot action needed; optionally the bot can proactively re-send the link before expiry if desired (not currently built — would need a new "resend" endpoint if wanted) |
| Link opened twice (once after payment already succeeded) | Page shows a generic "expired/unavailable" response — no duplicate charge | Normal, not an error to alert on |

---

## 8. What did NOT change

- No new order-creation endpoint — steps 1–3 are identical to any other guest checkout integration.
- No changes needed to how the bot builds cart items / addresses.
- No email/SMS/WhatsApp sending logic lives in Magento — entirely the bot's responsibility, unchanged.

## 9. What DID change vs. a hypothetical "normal storefront" integration

- `paymentMethod.method` value (`razerpay_payment_agent` instead of `razerpay_payment`).
- One new call after order placement (step 5) to fetch the payment link — this didn't exist before; there is no core Magento endpoint that returns a Fiuu hosted-payment URL.
- Requires an Integration OAuth token (new credential to store) for step 5 only.
