{
  "openapi": "3.1.0",
  "info": {
    "title": "Pay2S Card Popup API",
    "version": "1.0.0",
    "description": "HMAC SHA256 trên pay2s-card-popup-v1, timestamp, SHA256 nguyên văn JSON body, nối bằng LF. Chỉ gọi từ backend."
  },
  "servers": [
    {
      "url": "https://payment.pay2s.vn"
    }
  ],
  "paths": {
    "/api/card-popup-session.php": {
      "post": {
        "operationId": "cardPopupSession",
        "summary": "Tạo phiên hoặc tra cứu đơn thẻ",
        "parameters": [
          {
            "name": "X-Pay2S-Partner",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "partnerCode"
          },
          {
            "name": "X-Pay2S-Access-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "accessKey"
          },
          {
            "name": "X-Pay2S-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Unix seconds, ±300s"
          },
          {
            "name": "X-Pay2S-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "HMAC SHA256 hex"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "orderId",
                      "amount",
                      "cardBrand",
                      "buyer",
                      "merchantOrigin",
                      "webhookUrl"
                    ],
                    "properties": {
                      "action": {
                        "const": "create",
                        "default": "create"
                      },
                      "orderId": {
                        "type": "string",
                        "description": "Mã đơn duy nhất theo tài khoản/cửa hàng",
                        "pattern": "^[A-Za-z0-9._:-]{1,128}$"
                      },
                      "amount": {
                        "type": "integer",
                        "minimum": 2000,
                        "maximum": 2147483646
                      },
                      "cardBrand": {
                        "type": "string",
                        "enum": [
                          "visa",
                          "mastercard",
                          "jcb",
                          "amex",
                          "unionpay"
                        ]
                      },
                      "buyer": {
                        "type": "object",
                        "required": [
                          "firstName",
                          "lastName",
                          "email"
                        ],
                        "properties": {
                          "firstName": {
                            "type": "string",
                            "description": "Tên",
                            "minLength": 1,
                            "maxLength": 30
                          },
                          "lastName": {
                            "type": "string",
                            "description": "Họ và tên đệm",
                            "minLength": 1,
                            "maxLength": 30
                          },
                          "email": {
                            "type": "string",
                            "description": "Email",
                            "format": "email",
                            "maxLength": 40
                          }
                        }
                      },
                      "merchantOrigin": {
                        "type": "string",
                        "description": "HTTPS origin không có đường dẫn",
                        "format": "uri"
                      },
                      "webhookUrl": {
                        "type": "string",
                        "description": "Webhook HTTPS công khai",
                        "format": "uri"
                      },
                      "sandboxOnly": {
                        "type": "boolean",
                        "default": false,
                        "description": "true từ chối kết nối production"
                      },
                      "connectionId": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "ID đã lưu. Bỏ qua để chọn kết nối mặc định."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "action",
                      "orderId"
                    ],
                    "properties": {
                      "action": {
                        "const": "status"
                      },
                      "orderId": {
                        "type": "string",
                        "maxLength": 128
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "action"
                    ],
                    "properties": {
                      "action": {
                        "const": "connections"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Đã xử lý",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sessionId": {
                          "type": "string",
                          "description": "ID phiên",
                          "pattern": "^[a-f0-9]{64}$"
                        },
                        "orderId": {
                          "type": "string"
                        },
                        "environment": {
                          "enum": [
                            "sandbox",
                            "production"
                          ]
                        },
                        "expiresAt": {
                          "type": "integer"
                        },
                        "popupUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "status": {
                          "enum": [
                            "ready",
                            "pending",
                            "paid",
                            "failed",
                            "cancelled",
                            "review",
                            "expired"
                          ]
                        },
                        "amount": {
                          "type": "integer"
                        },
                        "merchantOrigin": {
                          "type": "string"
                        },
                        "launched": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Chưa bật API",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Không tìm thấy đơn",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Dữ liệu/xác thực/điều kiện không hợp lệ",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Body quá lớn",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Giới hạn yêu cầu",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Dịch vụ chưa sẵn sàng",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}