Refunds, and What's Still Unwritten

ជំពូកនេះមិនទាន់ត្រូវបានបកប្រែជាភាសាខ្មែរនៅឡើយទេ — សូមអានជាភាសាអង់គ្លេសខាងក្រោម។

Table of Contents

  1. Why this chapter is shorter than the others
  2. What's confirmed about the Refund API
  3. Callback verification and idempotency: not yet covered
  4. Beginner Pitfalls

1. Why this chapter is shorter than the others

Every other chapter in this course is backed by a hash formula or endpoint that was actually implemented and run against the sandbox. Refunds, callback signature verification, and idempotent order updates weren't — they're genuinely unfinished parts of the source project this course is based on. Rather than fabricate a hash formula or a verification scheme that was never tested, this chapter states plainly what's confirmed, and what isn't.

2. What's confirmed about the Refund API

PayWay's sandbox issues an RSA public/private key pair alongside the Public Key used everywhere else in this course (Part 1). That RSA key pair's purpose is confirmed for one specific thing: the Refund API requires a merchant_auth field built like this:

  1. Build a plain object: { mc_id, tran_id, refund_amount }.
  2. JSON-encode it.
  3. RSA-encrypt the JSON string with PAYWAY_RSA_PUBLIC_KEY, in 117-byte chunks.
  4. Base64-encode the encrypted chunks.

This is a meaningfully different mechanism from the hash field used in Part 3 and Part 4: hash only proves a request wasn't tampered with — PayWay can recompute it and compare. merchant_auth actually hides those values from anyone who intercepts the request, because encryption (not just hashing) is reversible only with the matching private key.

Beyond this, the Refund API's endpoint URL, remaining request fields, and response shape were never exercised against the sandbox for this course — verify those against the current official docs before implementing a refund flow for real. PAYWAY_RSA_PRIVATE_KEY's purpose remains unconfirmed by anything in this course; it wasn't referenced by the Purchase or Refund API docs checked while writing it.

3. Callback verification and idempotency: not yet covered

Part 5 left two explicit TODOs in the callback handler:

  • Verifying the callback is genuinely from PayWay, not spoofed by someone who guessed your return_url.
  • Idempotency — handling PayWay retrying a callback delivery (network blips happen) without double-crediting an order, and handling the callback and the polling result from Part 4 arriving in either order without conflicting.

Neither is implemented in this course's example, and neither should be treated as a small addition — signature verification in particular depends on details (which header, which algorithm, which key) that need confirming against PayWay's current docs before writing any code, the same way every hash formula in this course was.

If you're integrating for real, this is the next thing to build, and the source repository is the place to check for whether it's been written up since.

4. Beginner Pitfalls

  • Don't reuse the hash pattern from Parts 3–4 for merchant_auth. One is a keyed hash for tamper-detection; the other is actual encryption for confidentiality. They solve different problems and aren't interchangeable.
  • Don't ship a callback handler with the TODOs from Part 5 still open and call it done — an unverified callback means anyone who can guess or discover your return_url can mark orders as paid.
  • Treat every unconfirmed detail flagged in this chapter (the Refund API's full request/response shape, PAYWAY_RSA_PRIVATE_KEY's purpose) as exactly that — unconfirmed — rather than assuming this course would have mentioned it if it mattered.

ទិញកាហ្វេជូនខ្ញុំ

ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!