# WeChat Pay simulator test keys (DEV ONLY)

These self-signed keys let `DaProductAppWeb.WechatSimulatorController` stand in
for real WeChat Pay in development. They are **not secrets** and must never be
used against the real WeChat Pay API.

Regenerate with:

```sh
openssl genrsa -out platform_key.pem 2048
openssl req -new -x509 -key platform_key.pem -out platform_cert.pem \
  -days 3650 -subj "/CN=WeChatPaySimulatorPlatform"
openssl genrsa -out merchant_key.pem 2048
```

| file              | role                                                                    |
|-------------------|------------------------------------------------------------------------|
| `platform_key.pem`  | simulator signs simulated callbacks with this                        |
| `platform_cert.pem` | served (AEAD-encrypted) from `GET /sim/wechat/v3/certificates`; the app verifies callback signatures against it |
| `merchant_key.pem`  | the app loads this as `:wechat_private_key_path` to sign its outbound calls (simulator does not check it) |

## Usage

1. Start the app (`mix phx.server`, dev, port 4012).
2. Trigger a payment via `POST /api/processTransaction` with `provider: 7`.
   The provider now calls the simulator and gets a `code_url`; the transaction
   row is left `pending` / `QR_GENERATED`.
3. Simulate the customer paying:

   ```sh
   curl -s -X POST http://127.0.0.1:4012/sim/wechat/trigger-callback \
     -H 'content-type: application/json' \
     -d '{"m_ref_num":"sh_XXXXXXXXXXXXX","trade_state":"SUCCESS"}'
   ```

   The simulator builds a signed + AEAD-encrypted APIv3 notification and POSTs
   it to `/api/wechat/notify_payment`. Use `"trade_state":"CLOSED"` (or
   `PAYERROR`, `REVOKED`) to simulate a failed payment.
4. The webhook verifies the signature against the simulator's platform cert,
   decrypts the resource, and flips the transaction to `success` / `failed`.
