{
  "openapi": "3.0.3",
  "info": {
    "title": "SlipMatrix Merchant API",
    "version": "2026-10-11",
    "description": "Public merchant endpoints. Asynchronous verification: HTTP 201 only acknowledges submission. Confirm amount, receiver, currency and transfer date before fulfilling an order. Webhook contract is available in components.schemas.Webhook; payload is not enveloped.",
    "contact": {
      "name": "ByteMatrix Co., Ltd.",
      "email": "contact@bytematrix.co.th",
      "url": "https://www.bytematrix.co.th"
    }
  },
  "servers": [
    {
      "url": "https://api.slipmatrix.com/api",
      "description": "Production — คำขอตรวจสลิปอาจใช้เครดิตจริง"
    }
  ],
  "externalDocs": {
    "description": "คู่มือภาษาไทยและ Signed Webhook",
    "url": "https://slipmatrix.com/developers"
  },
  "security": [
    {
      "AppId": [],
      "ApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Verification"
    },
    {
      "name": "Batch"
    },
    {
      "name": "Results"
    },
    {
      "name": "Orders"
    }
  ],
  "paths": {
    "/verify": {
      "post": {
        "operationId": "verifySlip",
        "tags": [
          "Verification"
        ],
        "summary": "ส่งเลขอ้างอิงสลิป",
        "description": "ส่ง transRef และรหัสธนาคารผู้โอนจากสลิปจริง",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listTransactions",
        "tags": [
          "Results"
        ],
        "summary": "ดูประวัติรายการ",
        "description": "อ่านรายการที่ body.data.data; กรองวันที่สร้างรายการ createdAt ไม่ใช่เวลาโอน; วันที่ YYYY-MM-DD ใช้เขตเวลา Bangkok",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "เลขหน้า เริ่มที่ 1",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "จำนวนต่อหน้า ใช้จำนวนเต็มบวก",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "สถานะที่ต้องการ",
            "schema": {
              "type": "string",
              "description": "สถานะรายการ",
              "enum": [
                "PENDING",
                "PROCESSING",
                "VERIFIED",
                "FAILED",
                "DUPLICATE",
                "INVALID",
                "INSUFFICIENT_CREDIT"
              ]
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "YYYY-MM-DD หรือ ISO 8601 พร้อมเขตเวลา",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "YYYY-MM-DD หรือ ISO 8601 พร้อมเขตเวลา",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "อ่านรายการที่ body.data.data; กรองวันที่สร้างรายการ createdAt ไม่ใช่เวลาโอน; วันที่ YYYY-MM-DD ใช้เขตเวลา Bangkok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่ได้รับอนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/truewallet/file": {
      "post": {
        "operationId": "verifyTrueMoneyFile",
        "tags": [
          "Verification"
        ],
        "summary": "ส่งภาพสลิป TrueMoney Wallet",
        "description": "ต้องตั้งค่าผู้ให้บริการที่ได้รับอนุญาตก่อนใช้ และยังต้องทดสอบจริงก่อนเปิดใช้งาน ไม่มีการยืนยันจาก SCB ใช้เฉพาะหลักฐานเบอร์ผู้รับเต็ม ไม่ใช้เบอร์ที่ปิดบัง orderId ผูกได้เฉพาะออเดอร์ TRUEWALLET; ออเดอร์ BANK ถูกปฏิเสธ ส่งภาพเดิมและบริบทเดิมซ้ำคืน transactionId เดิม ติดตาม /verify/{transactionId} ก่อนส่งสินค้า",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/WalletFileUpload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "ภาพ Wallet เกิน 4 MiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/qr": {
      "post": {
        "operationId": "verifyQr",
        "tags": [
          "Verification"
        ],
        "summary": "ส่งข้อความ QR",
        "description": "ใช้ QR ของสลิปเต็มอย่างน้อย 50 ตัวอักษร ไม่ใช่ QR รับเงิน",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QrRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/image": {
      "post": {
        "operationId": "verifyImage",
        "tags": [
          "Verification"
        ],
        "summary": "ส่งภาพ Base64",
        "description": "JSON body รวมไม่เกิน 10 MiB ภาพ JPEG/PNG/WEBP แนะนำ multipart เพื่อลดขนาดคำขอ",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/image/url": {
      "post": {
        "operationId": "verifyImageUrl",
        "tags": [
          "Verification"
        ],
        "summary": "ตรวจสลิปจาก URL รูปภาพ",
        "description": "ดาวน์โหลดรูปสาธารณะผ่าน HTTPS สูงสุด 5 MiB ภายใน 10 วินาที ไม่รับ IP ภายในหรือ redirect ก่อนส่งตรวจ QR และเงื่อนไขรับเงิน",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UrlRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/image/upload": {
      "post": {
        "operationId": "verifyFile",
        "tags": [
          "Verification"
        ],
        "summary": "อัปโหลดภาพสลิป",
        "description": "ส่งไฟล์ใน field file; JPEG/PNG/WEBP ไม่เกิน 5 MiB",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FileRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับเข้าคิว ไม่ใช่การยืนยันชำระเงิน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/batch": {
      "post": {
        "operationId": "verifyBatch",
        "tags": [
          "Batch"
        ],
        "summary": "ส่งหลายเลขอ้างอิง",
        "description": "1–50 รายการ; รับได้บางส่วน; referenceId ใช้จับคู่ผล ไม่ใช่ idempotency key",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับ batch แล้ว ต้องอ่าน results ทุกแถวและติดตาม transactionId แยกกัน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/batch/images": {
      "post": {
        "operationId": "verifyBatchImages",
        "tags": [
          "Batch"
        ],
        "summary": "ส่งหลายภาพ Base64",
        "description": "1–20 ภาพ; JSON body รวมไม่เกิน 10 MiB; ตรวจผลแต่ละรายการ",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchImageRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับ batch แล้ว ต้องอ่าน results ทุกแถวและติดตาม transactionId แยกกัน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/batch/images/upload": {
      "post": {
        "operationId": "verifyBatchFiles",
        "tags": [
          "Batch"
        ],
        "summary": "อัปโหลดหลายภาพ",
        "description": "ส่ง field files ซ้ำ 1–20 ไฟล์ แต่ละไฟล์ไม่เกิน 5 MiB; referenceIds คั่น comma เรียงตามไฟล์",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/BatchFileRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "รับ batch แล้ว ต้องอ่าน results ทุกแถวและติดตาม transactionId แยกกัน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/{transactionId}": {
      "get": {
        "operationId": "getTransaction",
        "tags": [
          "Results"
        ],
        "summary": "ติดตามผลตรวจ",
        "description": "อ่าน body.data; HTTP 200 พร้อม data: null หากไม่พบหรือไม่มีสิทธิ์อ่านรายการ",
        "parameters": [
          {
            "name": "transactionId",
            "in": "path",
            "required": true,
            "description": "เลขรายการจากคำขอแรก",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "อ่าน body.data; HTTP 200 พร้อม data: null หากไม่พบหรือไม่มีสิทธิ์อ่านรายการ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่ได้รับอนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/verify/banks": {
      "get": {
        "operationId": "listBanks",
        "tags": [
          "Results"
        ],
        "summary": "ดูรหัสธนาคาร",
        "description": "ไม่ต้องส่ง Credentials; อ่านรายการที่ body.data.data เป็นข้อมูลรหัสธนาคาร ไม่ใช่คำรับประกันการตรวจทุกสลิป",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "ไม่ต้องส่ง Credentials; อ่านรายการที่ body.data.data เป็นข้อมูลรหัสธนาคาร ไม่ใช่คำรับประกันการตรวจทุกสลิป",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BanksResponse"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "operationId": "createOrder",
        "tags": [
          "Orders"
        ],
        "summary": "สร้างออเดอร์รับเงิน PromptPay หรือ TrueMoney",
        "description": "สร้างออเดอร์ที่ตรึงผู้รับ ยอด และเวลารับเงิน ก่อนส่งสลิปพร้อม orderId; BANK เป็นค่าเริ่มต้นและสร้าง PromptPay QR ซึ่งไม่ยืนยันการรับเงิน; TRUEWALLET ใช้เบอร์ผู้รับเต็มและไม่สร้าง QR โดยต้องเปิดผู้ให้บริการ Wallet ก่อนตรวจสลิป",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "ออเดอร์ใหม่หรือออเดอร์เดิมจาก reference และเงื่อนไขเดิม",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "ข้อมูลไม่ถูกต้อง สลิปซ้ำ เครดิตไม่พอ ออเดอร์ปิดแล้ว หรือ VERIFICATION_CONTEXT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่อยู่ในรายการที่ร้านหรือ API key อนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ORDER_REFERENCE_CONFLICT: reference เดิมมีเงื่อนไขต่างกัน",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "รอ Retry-After ก่อนลองใหม่",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "บริการไม่พร้อม หากมี transactionId ให้ติดตามรายการเดิม; คิวขัดข้องหลังบันทึก durable request จะยังคืน PENDING เพื่อกู้คืนอัตโนมัติ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listOrders",
        "tags": [
          "Orders"
        ],
        "summary": "รายการออเดอร์",
        "description": "รายการของร้านนี้เท่านั้น; ตัวระบุผู้รับถูกปิดบัง",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "กรองสถานะ",
            "schema": {
              "type": "string",
              "description": "สถานะออเดอร์",
              "enum": [
                "OPEN",
                "PAID",
                "CANCELLED",
                "EXPIRED"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "เลขหน้าเริ่มที่ 1",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "จำนวนต่อหน้า 1–100",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "รายการของร้านนี้เท่านั้น; ตัวระบุผู้รับถูกปิดบัง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่ได้รับอนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders/{orderId}": {
      "get": {
        "operationId": "getOrder",
        "tags": [
          "Orders"
        ],
        "summary": "อ่านออเดอร์และ QR",
        "description": "PAID และ paidTransactionId เป็นหลักฐานการปิดออเดอร์; 404 เมื่อไม่พบหรือเป็นของร้านอื่น",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "description": "ID ออเดอร์ของร้านคุณ",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PAID และ paidTransactionId เป็นหลักฐานการปิดออเดอร์; 404 เมื่อไม่พบหรือเป็นของร้านอื่น",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED: IP ผู้เรียกไม่ได้รับอนุญาต",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders/{orderId}/cancel": {
      "post": {
        "operationId": "cancelOrder",
        "tags": [
          "Orders"
        ],
        "summary": "ยกเลิกออเดอร์ที่ยังไม่ชำระ",
        "description": "ยกเลิกซ้ำได้; ห้ามยกเลิก PAID ผ่านเส้นทางนี้ ไม่คืนเงินจริง",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "description": "ID ออเดอร์ของร้านคุณ",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "สถานะออเดอร์ล่าสุด",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Credentials ไม่ถูกต้อง",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IP_NOT_ALLOWED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ORDER_ALREADY_PAID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "ลดความถี่คำขอ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AppId": {
        "type": "apiKey",
        "in": "header",
        "name": "x-app-id"
      },
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "VerificationRules": {
        "type": "object",
        "properties": {
          "receivers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "description": "ประเภทบัญชี",
                  "enum": [
                    "BANKAC",
                    "PROXY"
                  ]
                },
                "value": {
                  "type": "string",
                  "description": "เลขบัญชี/ตัวระบุ proxy เต็ม 6–20 หลัก ไม่ใช้เลขที่ถูกปิดบัง",
                  "pattern": "^\\d{6,20}$"
                },
                "proxyType": {
                  "type": "string",
                  "description": "ชนิด proxy จากธนาคาร ใช้กับ PROXY เท่านั้น",
                  "enum": [
                    "MSISDN",
                    "NATID",
                    "TAXID"
                  ]
                },
                "bankCode": {
                  "type": "string",
                  "description": "รหัสธนาคาร 3 หลัก จำเป็นสำหรับ BANKAC",
                  "pattern": "^\\d{3}$"
                }
              },
              "required": [
                "type",
                "value"
              ],
              "additionalProperties": false
            }
          },
          "expectedAmount": {
            "type": "string",
            "description": "ยอด THB ที่ต้องตรง แบบ decimal string ไม่เกิน 2 ตำแหน่ง"
          },
          "minAmount": {
            "type": "string",
            "description": "ยอด THB ขั้นต่ำ รวมขอบเขต"
          },
          "maxAmount": {
            "type": "string",
            "description": "ยอด THB ขั้นสูง รวมขอบเขต"
          },
          "transferAfter": {
            "type": "string",
            "description": "วันเวลาโอนขั้นต่ำ ISO พร้อม timezone รวมขอบเขต",
            "format": "date-time"
          },
          "transferBefore": {
            "type": "string",
            "description": "วันเวลาโอนขั้นสูง ISO พร้อม timezone รวมขอบเขต",
            "format": "date-time"
          },
          "orderReference": {
            "type": "string",
            "description": "เลขออเดอร์เพื่ออ้างอิง ไม่ใช่การสร้างหรือปิดยอดออเดอร์อัตโนมัติ",
            "maxLength": 100
          }
        },
        "additionalProperties": false,
        "description": "เงื่อนไขเสริมที่ต้องผ่านพร้อมเงื่อนไขร้านและช่องทาง ห้ามใช้เลขบัญชีปิดบังเพื่ออนุมัติ สลิปจริงที่ไม่ผ่านจะเป็น INVALID และไม่หักเครดิต"
      },
      "MatchingResult": {
        "type": "object",
        "properties": {
          "bankVerified": {
            "type": "boolean"
          },
          "walletVerified": {
            "type": "boolean",
            "description": "หลักฐานจากผู้ให้บริการ Wallet; ไม่ใช่การยืนยันจาก SCB"
          },
          "accepted": {
            "type": "boolean"
          },
          "checks": {
            "type": "object",
            "properties": {
              "receiver": {
                "type": "boolean",
                "nullable": true,
                "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
              },
              "amount": {
                "type": "boolean",
                "nullable": true,
                "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
              },
              "date": {
                "type": "boolean",
                "nullable": true,
                "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
              },
              "order": {
                "type": "boolean",
                "description": "ตรวจและปิดออเดอร์เดียวกันแบบ atomic สำเร็จหรือไม่ (มีเฉพาะคำขอที่ผูกออเดอร์)"
              }
            },
            "required": [
              "receiver",
              "amount",
              "date"
            ]
          },
          "failures": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "bankVerified",
          "accepted",
          "checks",
          "failures"
        ]
      },
      "UrlRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "imageUrl": {
            "type": "string",
            "description": "URL รูป JPEG/PNG/WebP สาธารณะผ่าน HTTPS พอร์ต 443 สูงสุด 5 MiB ภายใน 10 วินาที ไม่ตาม redirect",
            "format": "uri",
            "maxLength": 2048
          },
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          }
        },
        "required": [
          "imageUrl"
        ],
        "additionalProperties": false
      },
      "VerifyRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "transRef": {
            "type": "string",
            "description": "เลขอ้างอิงจากสลิปจริง อย่างน้อย 10 ตัวอักษร",
            "minLength": 10
          },
          "sendingBank": {
            "type": "string",
            "description": "รหัสธนาคารผู้โอน เก็บเป็นข้อความ 3 หลัก เช่น 014",
            "example": "014"
          },
          "qrData": {
            "type": "string",
            "description": "ข้อความ QR จากสลิป (ถ้ามี)"
          },
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          }
        },
        "required": [
          "transRef",
          "sendingBank"
        ],
        "additionalProperties": false
      },
      "QrRequest": {
        "type": "object",
        "properties": {
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          },
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "qrData": {
            "type": "string",
            "description": "ข้อความ QR เต็มจากสลิปจริง ไม่ใช่ QR สำหรับรับเงิน",
            "minLength": 50
          }
        },
        "required": [
          "qrData"
        ],
        "additionalProperties": false
      },
      "ImageRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          },
          "imageBase64": {
            "type": "string",
            "description": "ภาพ JPEG, PNG หรือ WEBP แบบ Base64 หรือ Data URI; JSON body ทั้งคำขอไม่เกิน 10 MiB"
          }
        },
        "required": [
          "imageBase64"
        ],
        "additionalProperties": false
      },
      "FileRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "rules": {
            "type": "string",
            "description": "JSON ของ VerificationRules สำหรับไฟล์นี้"
          },
          "file": {
            "type": "string",
            "description": "ไฟล์ JPEG, PNG หรือ WEBP ไม่เกิน 5 MiB (5,242,880 bytes)",
            "format": "binary"
          }
        },
        "required": [
          "file"
        ]
      },
      "BatchItem": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "transRef": {
            "type": "string",
            "description": "เลขอ้างอิงจากสลิปจริง อย่างน้อย 10 ตัวอักษร",
            "minLength": 10
          },
          "sendingBank": {
            "type": "string",
            "description": "รหัสธนาคารผู้โอน เก็บเป็นข้อความ 3 หลัก เช่น 014",
            "example": "014"
          },
          "qrData": {
            "type": "string",
            "description": "ข้อความ QR จากสลิป (ถ้ามี)"
          },
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          },
          "referenceId": {
            "type": "string",
            "description": "เลขอ้างอิงของคุณ ส่งกลับในผลลัพธ์; ไม่ใช่ idempotency key"
          }
        },
        "required": [
          "transRef",
          "sendingBank"
        ],
        "additionalProperties": false
      },
      "BatchRequest": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            },
            "description": "สลิป 1–50 รายการ"
          }
        },
        "required": [
          "items"
        ],
        "additionalProperties": false
      },
      "BatchImageItem": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "rules": {
            "$ref": "#/components/schemas/VerificationRules"
          },
          "imageBase64": {
            "type": "string",
            "description": "ภาพ JPEG, PNG หรือ WEBP แบบ Base64 หรือ Data URI; JSON body ทั้งคำขอไม่เกิน 10 MiB"
          },
          "referenceId": {
            "type": "string",
            "description": "เลขอ้างอิงของคุณ (ไม่บังคับ)"
          }
        },
        "required": [
          "imageBase64"
        ],
        "additionalProperties": false
      },
      "BatchImageRequest": {
        "type": "object",
        "properties": {
          "images": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/BatchImageItem"
            },
            "description": "ภาพแบบ Base64 1–20 ภาพ; รวม JSON ไม่เกิน 10 MiB"
          }
        },
        "required": [
          "images"
        ],
        "additionalProperties": false
      },
      "BatchFileRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "rules": {
            "type": "string",
            "description": "JSON ของ VerificationRules ใช้ร่วมกันทุกไฟล์"
          },
          "files": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "type": "string",
              "format": "binary"
            },
            "description": "ส่ง field files ซ้ำ 1–20 ไฟล์; แต่ละไฟล์ JPEG/PNG/WEBP ไม่เกิน 5 MiB"
          },
          "referenceIds": {
            "type": "string",
            "description": "รายการอ้างอิงคั่นด้วย comma เรียงตามไฟล์ เช่น order-001,order-002"
          }
        },
        "required": [
          "files"
        ]
      },
      "Accepted": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "transactionId": {
                "type": "string",
                "description": "เลขรายการสำหรับติดตามผล"
              },
              "status": {
                "type": "string",
                "description": "คำขอใหม่เป็น PENDING/PROCESSING; ส่งซ้ำสลิปเดิมพร้อม orderId และ rules เดิมจะคืนรายการเดิม ซึ่งอาจเป็นสถานะสุดท้ายแล้ว โดยไม่หักเครดิตซ้ำ",
                "enum": [
                  "PENDING",
                  "PROCESSING",
                  "VERIFIED",
                  "FAILED",
                  "DUPLICATE",
                  "INVALID",
                  "INSUFFICIENT_CREDIT"
                ]
              },
              "message": {
                "type": "string",
                "description": "ข้อความประกอบ"
              },
              "qrData": {
                "type": "string",
                "description": "QR ที่อ่านได้จากภาพ (ถ้ามี)"
              }
            },
            "required": [
              "transactionId",
              "status",
              "message"
            ]
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "Result": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "description": "เลขรายการ"
          },
          "status": {
            "type": "string",
            "description": "สถานะรายการ",
            "enum": [
              "PENDING",
              "PROCESSING",
              "VERIFIED",
              "FAILED",
              "DUPLICATE",
              "INVALID",
              "INSUFFICIENT_CREDIT"
            ]
          },
          "statusText": {
            "type": "string",
            "description": "ข้อความสถานะ"
          },
          "transRef": {
            "type": "string",
            "description": "เลขอ้างอิงธนาคาร หรือ hash ภาพส่งตรวจ Wallet; hash ภาพไม่ใช่เลขธุรกรรมการชำระเงิน"
          },
          "paymentRail": {
            "type": "string",
            "description": "ประเภทการชำระ",
            "enum": [
              "BANK",
              "TRUEWALLET"
            ]
          },
          "verificationProvider": {
            "type": "string",
            "description": "ผู้ตรวจหลักฐาน",
            "enum": [
              "SCB",
              "EASYSLIP"
            ]
          },
          "providerReference": {
            "type": "string",
            "description": "เลขธุรกรรม Wallet จากผู้ให้บริการ ใช้ตรวจการชำระซ้ำ"
          },
          "amount": {
            "type": "string",
            "description": "ยอดเงินทศนิยมแบบ string เช่น 100.00"
          },
          "paidLocalAmount": {
            "type": "string",
            "description": "ยอดชำระในสกุลเงินท้องถิ่น"
          },
          "paidLocalCurrency": {
            "type": "string",
            "description": "รหัสสกุลเงินแบบตัวเลข เช่น 764"
          },
          "currencyName": {
            "type": "string",
            "description": "ชื่อสกุลเงิน เช่น THB"
          },
          "transferDate": {
            "type": "string",
            "description": "วันเวลาโอน ISO 8601 พร้อมเขตเวลา",
            "format": "date-time"
          },
          "countryCode": {
            "type": "string",
            "description": "รหัสประเทศ"
          },
          "errorMessage": {
            "type": "string",
            "description": "รายละเอียดเมื่อไม่ผ่าน"
          },
          "matchingResult": {
            "$ref": "#/components/schemas/MatchingResult"
          },
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "orderPaid": {
            "type": "boolean",
            "description": "true เฉพาะรายการนี้ปิดออเดอร์ที่ลงทะเบียนเป็น PAID แล้ว; ต้องตรวจลายเซ็นและเทียบ orderId ฝั่งร้านก่อนส่งสินค้า"
          },
          "orderReference": {
            "type": "string",
            "description": "เลขออเดอร์ที่ลงทะเบียน หรืออ้างอิงจากคำขอ ถ้ามี"
          },
          "senderName": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderDisplayName": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderAccount": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderAccountType": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderProxy": {
            "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              }
            ]
          },
          "receiverName": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverDisplayName": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverAccount": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverAccountType": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverProxy": {
            "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              }
            ]
          },
          "senderNameMasked": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "senderAccountMasked": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "sendingBank": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "sendingBankName": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "receivingBank": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "receivingBankName": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref1": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref2": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref3": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          }
        },
        "required": [
          "transactionId",
          "status",
          "statusText",
          "transRef"
        ]
      },
      "BatchResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "results": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "index": {
                      "type": "integer",
                      "description": "ลำดับเริ่มที่ 0"
                    },
                    "referenceId": {
                      "type": "string",
                      "description": "อ้างอิงจากคำขอ"
                    },
                    "transactionId": {
                      "type": "string",
                      "description": "เลขรายการ ถ้ามี"
                    },
                    "transRef": {
                      "type": "string",
                      "description": "เลขอ้างอิงสลิป ถ้ามี"
                    },
                    "status": {
                      "type": "string",
                      "description": "ผลรับคำขอของแต่ละรายการ ไม่ใช่ผลตรวจสุดท้าย",
                      "enum": [
                        "PENDING",
                        "DUPLICATE",
                        "INSUFFICIENT_CREDIT",
                        "INVALID_QR",
                        "ERROR"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "รายละเอียด"
                    },
                    "qrData": {
                      "type": "string",
                      "description": "QR ที่อ่านได้ ถ้ามี"
                    }
                  },
                  "required": [
                    "index",
                    "status",
                    "message"
                  ]
                }
              },
              "submitted": {
                "type": "integer"
              },
              "errors": {
                "type": "integer"
              }
            },
            "required": [
              "results",
              "submitted",
              "errors"
            ]
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "Bank": {
        "type": "object",
        "properties": {
          "bankCode": {
            "type": "string",
            "description": "รหัสธนาคาร"
          },
          "bankAbbrevEn": {
            "type": "string",
            "description": "ชื่อย่อ"
          },
          "bankNameTh": {
            "type": "string",
            "description": "ชื่อภาษาไทย"
          }
        },
        "required": [
          "bankCode",
          "bankAbbrevEn",
          "bankNameTh"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "statusCode": {
            "type": "integer"
          },
          "message": {
            "description": "อาจเป็นข้อความ รายการข้อความ หรือ object",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "code": {
            "type": "string",
            "description": "รหัสข้อผิดพลาด ถ้ามี"
          },
          "transactionId": {
            "type": "string",
            "description": "เลขรายการของคุณ ถ้ามี ให้ติดตามก่อนส่งซ้ำ"
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "statusCode",
          "message",
          "timestamp"
        ]
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "transactionId": {
                "type": "string",
                "description": "เลขรายการ"
              },
              "status": {
                "type": "string",
                "description": "สถานะรายการ",
                "enum": [
                  "PENDING",
                  "PROCESSING",
                  "VERIFIED",
                  "FAILED",
                  "DUPLICATE",
                  "INVALID",
                  "INSUFFICIENT_CREDIT"
                ]
              },
              "statusText": {
                "type": "string",
                "description": "ข้อความสถานะ"
              },
              "transRef": {
                "type": "string",
                "description": "เลขอ้างอิงธนาคาร หรือ hash ภาพส่งตรวจ Wallet; hash ภาพไม่ใช่เลขธุรกรรมการชำระเงิน"
              },
              "paymentRail": {
                "type": "string",
                "description": "ประเภทการชำระ",
                "enum": [
                  "BANK",
                  "TRUEWALLET"
                ]
              },
              "verificationProvider": {
                "type": "string",
                "description": "ผู้ตรวจหลักฐาน",
                "enum": [
                  "SCB",
                  "EASYSLIP"
                ]
              },
              "providerReference": {
                "type": "string",
                "description": "เลขธุรกรรม Wallet จากผู้ให้บริการ ใช้ตรวจการชำระซ้ำ"
              },
              "amount": {
                "type": "string",
                "description": "ยอดเงินทศนิยมแบบ string เช่น 100.00"
              },
              "paidLocalAmount": {
                "type": "string",
                "description": "ยอดชำระในสกุลเงินท้องถิ่น"
              },
              "paidLocalCurrency": {
                "type": "string",
                "description": "รหัสสกุลเงินแบบตัวเลข เช่น 764"
              },
              "currencyName": {
                "type": "string",
                "description": "ชื่อสกุลเงิน เช่น THB"
              },
              "transferDate": {
                "type": "string",
                "description": "วันเวลาโอน ISO 8601 พร้อมเขตเวลา",
                "format": "date-time"
              },
              "countryCode": {
                "type": "string",
                "description": "รหัสประเทศ"
              },
              "errorMessage": {
                "type": "string",
                "description": "รายละเอียดเมื่อไม่ผ่าน"
              },
              "matchingResult": {
                "$ref": "#/components/schemas/MatchingResult"
              },
              "orderId": {
                "type": "string",
                "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
                "format": "uuid"
              },
              "orderPaid": {
                "type": "boolean",
                "description": "true เฉพาะรายการนี้ปิดออเดอร์ที่ลงทะเบียนเป็น PAID แล้ว; ต้องตรวจลายเซ็นและเทียบ orderId ฝั่งร้านก่อนส่งสินค้า"
              },
              "orderReference": {
                "type": "string",
                "description": "เลขออเดอร์ที่ลงทะเบียน หรืออ้างอิงจากคำขอ ถ้ามี"
              },
              "senderName": {
                "type": "string",
                "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "senderDisplayName": {
                "type": "string",
                "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "senderAccount": {
                "type": "string",
                "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "senderAccountType": {
                "type": "string",
                "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "senderProxy": {
                "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object"
                  }
                ]
              },
              "receiverName": {
                "type": "string",
                "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "receiverDisplayName": {
                "type": "string",
                "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "receiverAccount": {
                "type": "string",
                "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "receiverAccountType": {
                "type": "string",
                "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
              },
              "receiverProxy": {
                "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object"
                  }
                ]
              },
              "senderNameMasked": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "senderAccountMasked": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "sendingBank": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "sendingBankName": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "receivingBank": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "receivingBankName": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "ref1": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "ref2": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              },
              "ref3": {
                "type": "string",
                "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
              }
            },
            "required": [
              "transactionId",
              "status",
              "statusText",
              "transRef"
            ],
            "nullable": true,
            "description": "null หากไม่พบรายการในบัญชีของคุณ (ยังตอบ HTTP 200)"
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "HistoryResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "สถานะรายการ",
                      "enum": [
                        "PENDING",
                        "PROCESSING",
                        "VERIFIED",
                        "FAILED",
                        "DUPLICATE",
                        "INVALID",
                        "INSUFFICIENT_CREDIT"
                      ]
                    },
                    "statusText": {
                      "type": "string",
                      "description": "ข้อความสถานะ"
                    },
                    "transRef": {
                      "type": "string",
                      "description": "เลขอ้างอิงธนาคาร หรือ hash ภาพส่งตรวจ Wallet; hash ภาพไม่ใช่เลขธุรกรรมการชำระเงิน"
                    },
                    "paymentRail": {
                      "type": "string",
                      "description": "ประเภทการชำระ",
                      "enum": [
                        "BANK",
                        "TRUEWALLET"
                      ]
                    },
                    "verificationProvider": {
                      "type": "string",
                      "description": "ผู้ตรวจหลักฐาน",
                      "enum": [
                        "SCB",
                        "EASYSLIP"
                      ]
                    },
                    "providerReference": {
                      "type": "string",
                      "description": "เลขธุรกรรม Wallet จากผู้ให้บริการ ใช้ตรวจการชำระซ้ำ"
                    },
                    "paidLocalAmount": {
                      "type": "string",
                      "description": "ยอดชำระในสกุลเงินท้องถิ่น"
                    },
                    "paidLocalCurrency": {
                      "type": "string",
                      "description": "รหัสสกุลเงินแบบตัวเลข เช่น 764"
                    },
                    "currencyName": {
                      "type": "string",
                      "description": "ชื่อสกุลเงิน เช่น THB"
                    },
                    "transferDate": {
                      "type": "string",
                      "description": "วันเวลาโอน ISO 8601 พร้อมเขตเวลา",
                      "format": "date-time",
                      "nullable": true
                    },
                    "countryCode": {
                      "type": "string",
                      "description": "รหัสประเทศ"
                    },
                    "matchingResult": {
                      "$ref": "#/components/schemas/MatchingResult"
                    },
                    "orderId": {
                      "type": "string",
                      "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
                      "format": "uuid"
                    },
                    "orderPaid": {
                      "type": "boolean",
                      "description": "true เฉพาะรายการนี้ปิดออเดอร์ที่ลงทะเบียนเป็น PAID แล้ว; ต้องตรวจลายเซ็นและเทียบ orderId ฝั่งร้านก่อนส่งสินค้า"
                    },
                    "orderReference": {
                      "type": "string",
                      "description": "เลขออเดอร์ที่ลงทะเบียน หรืออ้างอิงจากคำขอ ถ้ามี"
                    },
                    "senderName": {
                      "type": "string",
                      "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง",
                      "nullable": true
                    },
                    "senderDisplayName": {
                      "type": "string",
                      "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
                    },
                    "senderAccount": {
                      "type": "string",
                      "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง",
                      "nullable": true
                    },
                    "senderAccountType": {
                      "type": "string",
                      "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
                    },
                    "senderProxy": {
                      "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object"
                        }
                      ]
                    },
                    "receiverName": {
                      "type": "string",
                      "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง",
                      "nullable": true
                    },
                    "receiverDisplayName": {
                      "type": "string",
                      "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
                    },
                    "receiverAccount": {
                      "type": "string",
                      "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง",
                      "nullable": true
                    },
                    "receiverAccountType": {
                      "type": "string",
                      "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
                    },
                    "receiverProxy": {
                      "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object"
                        }
                      ]
                    },
                    "senderNameMasked": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี",
                      "nullable": true
                    },
                    "senderAccountMasked": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี",
                      "nullable": true
                    },
                    "sendingBank": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "sendingBankName": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "receivingBank": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "receivingBankName": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "ref1": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "ref2": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "ref3": {
                      "type": "string",
                      "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
                    },
                    "id": {
                      "type": "string",
                      "description": "เลขรายการ ใช้แทน transactionId ในประวัติ"
                    },
                    "verifiedAmount": {
                      "type": "string",
                      "description": "ยอดที่ตรวจสอบแล้ว อาจเป็น null",
                      "nullable": true
                    },
                    "requestSource": {
                      "type": "string",
                      "description": "แหล่งคำขอ",
                      "enum": [
                        "API",
                        "LINE_WEBHOOK",
                        "TELEGRAM_WEBHOOK"
                      ]
                    },
                    "creditDeducted": {
                      "type": "boolean"
                    },
                    "webhookSent": {
                      "type": "boolean"
                    },
                    "createdAt": {
                      "type": "string",
                      "description": "เวลาสร้างรายการ",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "transRef",
                    "status",
                    "statusText",
                    "requestSource",
                    "creditDeducted",
                    "webhookSent",
                    "createdAt"
                  ]
                }
              },
              "total": {
                "type": "integer"
              },
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              }
            },
            "required": [
              "data",
              "total",
              "page",
              "limit"
            ]
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "BanksResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "success": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Bank"
                }
              }
            },
            "required": [
              "success",
              "data"
            ]
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "description": "เลขรายการ"
          },
          "status": {
            "type": "string",
            "description": "สถานะรายการ",
            "enum": [
              "PENDING",
              "PROCESSING",
              "VERIFIED",
              "FAILED",
              "DUPLICATE",
              "INVALID",
              "INSUFFICIENT_CREDIT"
            ]
          },
          "statusText": {
            "type": "string",
            "description": "ข้อความสถานะ"
          },
          "transRef": {
            "type": "string",
            "description": "เลขอ้างอิงธนาคาร หรือ hash ภาพส่งตรวจ Wallet; hash ภาพไม่ใช่เลขธุรกรรมการชำระเงิน"
          },
          "paymentRail": {
            "type": "string",
            "description": "ประเภทการชำระ",
            "enum": [
              "BANK",
              "TRUEWALLET"
            ]
          },
          "verificationProvider": {
            "type": "string",
            "description": "ผู้ตรวจหลักฐาน",
            "enum": [
              "SCB",
              "EASYSLIP"
            ]
          },
          "providerReference": {
            "type": "string",
            "description": "เลขธุรกรรม Wallet จากผู้ให้บริการ ใช้ตรวจการชำระซ้ำ"
          },
          "amount": {
            "type": "string",
            "description": "ยอดเงินทศนิยมแบบ string เช่น 100.00"
          },
          "paidLocalAmount": {
            "type": "string",
            "description": "ยอดชำระในสกุลเงินท้องถิ่น"
          },
          "paidLocalCurrency": {
            "type": "string",
            "description": "รหัสสกุลเงินแบบตัวเลข เช่น 764"
          },
          "currencyName": {
            "type": "string",
            "description": "ชื่อสกุลเงิน เช่น THB"
          },
          "transferDate": {
            "type": "string",
            "description": "วันเวลาโอน ISO 8601 พร้อมเขตเวลา",
            "format": "date-time"
          },
          "countryCode": {
            "type": "string",
            "description": "รหัสประเทศ"
          },
          "errorMessage": {
            "type": "string",
            "description": "รายละเอียดเมื่อไม่ผ่าน"
          },
          "matchingResult": {
            "$ref": "#/components/schemas/MatchingResult"
          },
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "orderPaid": {
            "type": "boolean",
            "description": "true เฉพาะรายการนี้ปิดออเดอร์ที่ลงทะเบียนเป็น PAID แล้ว; ต้องตรวจลายเซ็นและเทียบ orderId ฝั่งร้านก่อนส่งสินค้า"
          },
          "orderReference": {
            "type": "string",
            "description": "เลขออเดอร์ที่ลงทะเบียน หรืออ้างอิงจากคำขอ ถ้ามี"
          },
          "senderName": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderDisplayName": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderAccount": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderAccountType": {
            "type": "string",
            "description": "ข้อมูลผู้โอน; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "senderProxy": {
            "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              }
            ]
          },
          "receiverName": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverDisplayName": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverAccount": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverAccountType": {
            "type": "string",
            "description": "ข้อมูลผู้รับ; อาจไม่ส่งกลับหรือถูกปิดบัง"
          },
          "receiverProxy": {
            "description": "ข้อมูล proxy จากธนาคาร (รูปแบบอาจต่างกัน)",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              }
            ]
          },
          "senderNameMasked": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "senderAccountMasked": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "sendingBank": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "sendingBankName": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "receivingBank": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "receivingBankName": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref1": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref2": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "ref3": {
            "type": "string",
            "description": "ข้อมูลเพิ่มเติมจากธนาคาร ถ้ามี"
          },
          "event": {
            "type": "string",
            "description": "เหตุการณ์",
            "enum": [
              "slip.verified",
              "slip.failed",
              "slip.duplicate"
            ]
          },
          "verifiedAt": {
            "type": "string",
            "description": "เวลาที่เตรียมผลส่ง Webhook ไม่ใช่เวลาโอน",
            "format": "date-time"
          }
        },
        "required": [
          "event",
          "transactionId",
          "transRef",
          "status",
          "statusText",
          "verifiedAt"
        ]
      },
      "WalletFileUpload": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "ภาพ TrueMoney JPEG/PNG/WebP/GIF ไม่เกิน 4 MiB",
            "format": "binary"
          },
          "orderId": {
            "type": "string",
            "description": "ID ของออเดอร์ที่สร้างผ่าน /orders; ผูกเงื่อนไขผู้รับ ยอด และเวลาที่เปลี่ยนไม่ได้",
            "format": "uuid"
          },
          "rules": {
            "type": "string",
            "description": "ข้อความ JSON ของ VerificationRules สำหรับสลิป Wallet; field ไม่เกิน 16 KiB ไม่ส่ง field ย่อย"
          }
        },
        "required": [
          "file"
        ],
        "additionalProperties": false
      },
      "CreateOrderRequest": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "description": "อ้างอิงไม่ซ้ำต่อร้าน ส่งเงื่อนไขเดิมซ้ำคืนออเดอร์เดิม; เปลี่ยนเงื่อนไขคืน 409",
            "pattern": "^[a-zA-Z0-9._/-]{1,100}$"
          },
          "amount": {
            "type": "string",
            "description": "ยอด THB ต้องมากกว่า 0 ไม่รับ JSON number",
            "pattern": "^(0|[1-9]\\d{0,9})(\\.\\d{1,2})?$"
          },
          "paymentRail": {
            "type": "string",
            "description": "BANK เป็นค่าเริ่มต้น; TRUEWALLET ใช้เบอร์ผู้รับ Wallet และไม่สร้าง QR",
            "enum": [
              "BANK",
              "TRUEWALLET"
            ],
            "default": "BANK"
          },
          "promptPayType": {
            "type": "string",
            "description": "เฉพาะ BANK",
            "enum": [
              "PHONE",
              "NATIONAL_ID"
            ]
          },
          "walletReceiverPhone": {
            "type": "string",
            "description": "เบอร์ผู้รับเต็มเฉพาะ TRUEWALLET",
            "pattern": "^(0[689]\\d{8}|0066[689]\\d{8})$"
          },
          "promptPayValue": {
            "type": "string",
            "description": "ตัวระบุผู้รับที่ลงทะเบียนครบถ้วน: PHONE เบอร์ 0[689] จำนวน 10 หลัก หรือ 0066 จำนวน 13 หลัก; NATIONAL_ID จำนวน 13 หลัก; QR เปิดเผยตัวระบุนี้"
          },
          "branchId": {
            "type": "string",
            "description": "ID สาขา ถ้ามี",
            "format": "uuid",
            "nullable": false
          },
          "expiresAt": {
            "type": "string",
            "description": "ISO timestamp พร้อม timezone มากกว่า 1 นาทีและไม่เกิน 7 วันในอนาคต; ไม่ส่งใช้ 30 นาที",
            "format": "date-time"
          }
        },
        "required": [
          "reference",
          "amount"
        ],
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "promptPayType",
              "promptPayValue"
            ],
            "properties": {
              "paymentRail": {
                "enum": [
                  "BANK"
                ]
              }
            },
            "not": {
              "required": [
                "walletReceiverPhone"
              ]
            }
          },
          {
            "required": [
              "paymentRail",
              "walletReceiverPhone"
            ],
            "properties": {
              "paymentRail": {
                "enum": [
                  "TRUEWALLET"
                ]
              }
            },
            "not": {
              "anyOf": [
                {
                  "required": [
                    "promptPayType"
                  ]
                },
                {
                  "required": [
                    "promptPayValue"
                  ]
                }
              ]
            }
          }
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID ออเดอร์",
            "format": "uuid"
          },
          "reference": {
            "type": "string",
            "description": "อ้างอิงออเดอร์ของร้าน"
          },
          "amount": {
            "type": "string",
            "description": "ยอด THB decimal string"
          },
          "currency": {
            "type": "string",
            "description": "สกุลเงิน",
            "enum": [
              "THB"
            ]
          },
          "paymentRail": {
            "type": "string",
            "description": "ประเภทออเดอร์",
            "enum": [
              "BANK",
              "TRUEWALLET"
            ]
          },
          "branchId": {
            "type": "string",
            "description": "ID สาขา ถ้ามี",
            "format": "uuid",
            "nullable": true
          },
          "promptPayType": {
            "type": "string",
            "description": "ชนิดผู้รับ BANK; null สำหรับ Wallet",
            "enum": [
              "PHONE",
              "NATIONAL_ID"
            ],
            "nullable": true
          },
          "promptPayMasked": {
            "type": "string",
            "description": "ผู้รับธนาคารที่ปิดบังในรายการ; null สำหรับ Wallet",
            "nullable": true
          },
          "walletReceiverMasked": {
            "type": "string",
            "description": "เบอร์ผู้รับ Wallet ที่ปิดบัง; null สำหรับ BANK",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "สถานะออเดอร์",
            "enum": [
              "OPEN",
              "PAID",
              "CANCELLED",
              "EXPIRED"
            ]
          },
          "createdAt": {
            "type": "string",
            "description": "สร้างออเดอร์",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "description": "หมดเวลารับคำขอใหม่",
            "format": "date-time"
          },
          "paidAt": {
            "type": "string",
            "description": "เวลาปิดออเดอร์",
            "format": "date-time",
            "nullable": true
          },
          "paidTransactionId": {
            "type": "string",
            "description": "รายการที่ปิดออเดอร์เพียงรายการเดียว",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "id",
          "reference",
          "amount",
          "currency",
          "paymentRail",
          "branchId",
          "promptPayType",
          "promptPayMasked",
          "walletReceiverMasked",
          "status",
          "createdAt",
          "expiresAt",
          "paidAt",
          "paidTransactionId"
        ]
      },
      "OrderDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID ออเดอร์",
            "format": "uuid"
          },
          "reference": {
            "type": "string",
            "description": "อ้างอิงออเดอร์ของร้าน"
          },
          "amount": {
            "type": "string",
            "description": "ยอด THB decimal string"
          },
          "currency": {
            "type": "string",
            "description": "สกุลเงิน",
            "enum": [
              "THB"
            ]
          },
          "paymentRail": {
            "type": "string",
            "description": "ประเภทออเดอร์",
            "enum": [
              "BANK",
              "TRUEWALLET"
            ]
          },
          "branchId": {
            "type": "string",
            "description": "ID สาขา ถ้ามี",
            "format": "uuid",
            "nullable": true
          },
          "promptPayType": {
            "type": "string",
            "description": "ชนิดผู้รับ BANK; null สำหรับ Wallet",
            "enum": [
              "PHONE",
              "NATIONAL_ID"
            ],
            "nullable": true
          },
          "promptPayMasked": {
            "type": "string",
            "description": "ผู้รับธนาคารที่ปิดบังในรายการ; null สำหรับ Wallet",
            "nullable": true
          },
          "walletReceiverMasked": {
            "type": "string",
            "description": "เบอร์ผู้รับ Wallet ที่ปิดบัง; null สำหรับ BANK",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "สถานะออเดอร์",
            "enum": [
              "OPEN",
              "PAID",
              "CANCELLED",
              "EXPIRED"
            ]
          },
          "createdAt": {
            "type": "string",
            "description": "สร้างออเดอร์",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "description": "หมดเวลารับคำขอใหม่",
            "format": "date-time"
          },
          "paidAt": {
            "type": "string",
            "description": "เวลาปิดออเดอร์",
            "format": "date-time",
            "nullable": true
          },
          "paidTransactionId": {
            "type": "string",
            "description": "รายการที่ปิดออเดอร์เพียงรายการเดียว",
            "format": "uuid",
            "nullable": true
          },
          "promptPayValue": {
            "type": "string",
            "description": "ผู้รับธนาคารเต็มสำหรับเจ้าของบัญชี; null สำหรับ Wallet",
            "nullable": true
          },
          "walletReceiverPhone": {
            "type": "string",
            "description": "เบอร์ Wallet เต็มเฉพาะเจ้าของบัญชี; null สำหรับ BANK",
            "nullable": true
          },
          "qrData": {
            "type": "string",
            "description": "PromptPay QR tag 29; null สำหรับ Wallet",
            "nullable": true
          },
          "qrImageDataUrl": {
            "type": "string",
            "description": "PNG data URL เฉพาะ OPEN; null หาก PAID/CANCELLED/EXPIRED",
            "nullable": true
          },
          "lastTransaction": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "รายการตรวจล่าสุด",
                "format": "uuid"
              },
              "status": {
                "type": "string",
                "description": "สถานะรายการ",
                "enum": [
                  "PENDING",
                  "PROCESSING",
                  "VERIFIED",
                  "FAILED",
                  "DUPLICATE",
                  "INVALID",
                  "INSUFFICIENT_CREDIT"
                ]
              },
              "errorMessage": {
                "type": "string",
                "description": "ข้อความไม่ผ่าน",
                "nullable": true
              },
              "matchingResult": {
                "type": "object",
                "properties": {
                  "bankVerified": {
                    "type": "boolean"
                  },
                  "walletVerified": {
                    "type": "boolean",
                    "description": "หลักฐานจากผู้ให้บริการ Wallet; ไม่ใช่การยืนยันจาก SCB"
                  },
                  "accepted": {
                    "type": "boolean"
                  },
                  "checks": {
                    "type": "object",
                    "properties": {
                      "receiver": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
                      },
                      "amount": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
                      },
                      "date": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "null หมายถึงไม่ได้กำหนดเงื่อนไข ไม่ใช่ตรวจผ่าน"
                      },
                      "order": {
                        "type": "boolean",
                        "description": "ตรวจและปิดออเดอร์เดียวกันแบบ atomic สำเร็จหรือไม่ (มีเฉพาะคำขอที่ผูกออเดอร์)"
                      }
                    },
                    "required": [
                      "receiver",
                      "amount",
                      "date"
                    ]
                  },
                  "failures": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "bankVerified",
                  "accepted",
                  "checks",
                  "failures"
                ],
                "nullable": true
              },
              "createdAt": {
                "type": "string",
                "description": "เวลาส่งตรวจ",
                "format": "date-time"
              }
            },
            "required": [
              "id",
              "status",
              "errorMessage",
              "matchingResult",
              "createdAt"
            ],
            "nullable": true
          }
        },
        "required": [
          "id",
          "reference",
          "amount",
          "currency",
          "paymentRail",
          "branchId",
          "promptPayType",
          "promptPayMasked",
          "walletReceiverMasked",
          "status",
          "createdAt",
          "expiresAt",
          "paidAt",
          "paidTransactionId",
          "promptPayValue",
          "walletReceiverPhone",
          "qrData",
          "qrImageDataUrl",
          "lastTransaction"
        ]
      },
      "OrderResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "$ref": "#/components/schemas/OrderDetail"
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      },
      "OrderListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Order"
                }
              },
              "total": {
                "type": "integer"
              },
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              }
            },
            "required": [
              "data",
              "total",
              "page",
              "limit"
            ]
          },
          "timestamp": {
            "type": "string",
            "description": "เวลาตอบกลับ ISO 8601 (Asia/Bangkok)",
            "format": "date-time"
          }
        },
        "required": [
          "success",
          "data",
          "timestamp"
        ]
      }
    }
  }
}
