VKL Shield Tài liệu API

Schema

Mọi schema OpenAPI dùng trong request/response body của v1.

V1Error

Body lỗi dùng chung cho mọi lỗi auth/registry/signing/origin/pool (SHIELD_KEY_*, SCOPE_DENIED, ORIGIN_NOT_ALLOWED, POOL_MISMATCH, SHIELD_REGISTRY_*, PAYMENT_ENV_MISMATCH, CAPTURED_PROOF_UNAVAILABLE). message/docs LUÔN có mặt. Khác với LegacyControllerError dưới đây — hình dạng lỗi theo từng endpoint của PayPal/Stripe — không bao giờ mang message/docs.

trườngkiểumô tả
errorbooleanbắt buộc
dataobjectbắt buộc
  • issue string bắt buộc

    Mọi mã issue một response v1 có thể mang. Nhóm đầu tiên (SHIELD_KEY_*, SCOPE_DENIED, ORIGIN_NOT_ALLOWED, POOL_MISMATCH, SHIELD_REGISTRY_*, SHIELD_ENV_MISCONFIGURED, PAYMENT_ENV_MISMATCH, SIGNING_UNAVAILABLE, LEGACY_API_DISABLED, CAPTURED_PROOF_UNAVAILABLE) là bảng auth/registry/signing v1 dùng chung (bảng V1_ISSUE_STATUS dùng chung — được contract-test khớp 1:1). Các mã còn lại là các issue validate/business theo từng endpoint do các controller PayPal/Stripe bên dưới trả về (cùng mã mà API legacy trả về cho cùng endpoint). NGOẠI LỆ: STRIPE_ERROR được liệt kê ở đây như giá trị fallback literal, nhưng response 500 của Stripe create-intent/complete KHÔNG đóng với enum này — xem StripeErrorPassthrough, nơi ghi lại issue là error.code mở của chính Stripe.

  • message string bắt buộc
  • docs string bắt buộc

LegacyControllerError

Body lỗi theo từng endpoint của PayPal/Stripe — CÙNG hình dạng mà API cũ (không-v1) luôn trả về cho các route này. Chỉ issue được đảm bảo; message/docs KHÔNG BAO GIỜ có mặt (khác với V1Error). Một vài response không mang data nào cả — xem mô tả riêng của từng response để biết body chính xác.

trườngkiểumô tả
errorbooleanbắt buộc
dataobjectbắt buộc
  • issue string bắt buộc

    Mọi mã issue một response v1 có thể mang. Nhóm đầu tiên (SHIELD_KEY_*, SCOPE_DENIED, ORIGIN_NOT_ALLOWED, POOL_MISMATCH, SHIELD_REGISTRY_*, SHIELD_ENV_MISCONFIGURED, PAYMENT_ENV_MISMATCH, SIGNING_UNAVAILABLE, LEGACY_API_DISABLED, CAPTURED_PROOF_UNAVAILABLE) là bảng auth/registry/signing v1 dùng chung (bảng V1_ISSUE_STATUS dùng chung — được contract-test khớp 1:1). Các mã còn lại là các issue validate/business theo từng endpoint do các controller PayPal/Stripe bên dưới trả về (cùng mã mà API legacy trả về cho cùng endpoint). NGOẠI LỆ: STRIPE_ERROR được liệt kê ở đây như giá trị fallback literal, nhưng response 500 của Stripe create-intent/complete KHÔNG đóng với enum này — xem StripeErrorPassthrough, nơi ghi lại issue là error.code mở của chính Stripe.

  • details array tùy chọn

    chi tiết validate theo field tùy chọn (ví dụ INVALID_SHIPPING_ADDRESS)

    mảng gồm:

  • status string tùy chọn

    echo trạng thái phía nhà cung cấp tùy chọn (ví dụ Stripe PaymentIntent.status khi NOT_SUCCEEDED)

  • message string tùy chọn

    chỉ có mặt khi STRIPE_ERROR (chuyển tiếp error.message của Stripe)

LegacyStringError

Body {error:string} trần không có data nào cả — khác với LegacyGateError (cùng hình dạng) và với V1Error/LegacyControllerError (có mang data). Dùng cho các lỗi cấu hình/nội bộ chung: "Shield misconfigured" (lệch chế độ key pk/sk của Stripe), "Internal server error" (lỗi không xác định), "Shield unavailable" (shield chưa được cấu hình secret trên route PayPal).

trườngkiểumô tả
errorstringbắt buộc

StripeErrorPassthrough

Body 500 trên /v1/stripe/create-intent và /v1/stripe/complete khi lời gọi API Stripe gốc throw lỗi. issue là MỞ — nó chuyển tiếp nguyên văn error.code của Stripe (ví dụ card_declined, parameter_invalid_integer, amount_too_small) khi Stripe đặt một giá trị, chỉ fallback về chuỗi literal STRIPE_ERROR khi không có. KHÔNG phải thành viên của enum đóng V1Issue — không validate issue dựa trên enum đó cho response này.

trườngkiểumô tả
errorbooleanbắt buộc
dataobjectbắt buộc
  • issue string bắt buộc

    error.code của Stripe, hoặc 'STRIPE_ERROR' khi Stripe không cung cấp

  • message string bắt buộc

    error.message của Stripe, hoặc 'unknown'

LegacyGateError

Body trần từ gate phân giải pk của Stripe và gate hostname của PayPal — error ở đây là một STRING, không phải true, và không có data/issue nào cả. Bao gồm Stripe MISSING_PK/UNKNOWN_PK/PK_POOL_MISMATCH và gate unknown-host/no-secret của PayPal; tên issue trong mô tả của từng response chỉ mang tính tài liệu, không bao giờ có mặt trong body thực tế.

trườngkiểumô tả
errorstringbắt buộc

V1Issue

Mọi mã issue một response v1 có thể mang. Nhóm đầu tiên (SHIELD_KEY_*, SCOPE_DENIED, ORIGIN_NOT_ALLOWED, POOL_MISMATCH, SHIELD_REGISTRY_*, SHIELD_ENV_MISCONFIGURED, PAYMENT_ENV_MISMATCH, SIGNING_UNAVAILABLE, LEGACY_API_DISABLED, CAPTURED_PROOF_UNAVAILABLE) là bảng auth/registry/signing v1 dùng chung (bảng V1_ISSUE_STATUS dùng chung — được contract-test khớp 1:1). Các mã còn lại là các issue validate/business theo từng endpoint do các controller PayPal/Stripe bên dưới trả về (cùng mã mà API legacy trả về cho cùng endpoint). NGOẠI LỆ: STRIPE_ERROR được liệt kê ở đây như giá trị fallback literal, nhưng response 500 của Stripe create-intent/complete KHÔNG đóng với enum này — xem StripeErrorPassthrough, nơi ghi lại issue là error.code mở của chính Stripe.

enum: SHIELD_KEY_INVALID, SHIELD_KEY_ENV_MISMATCH, SHIELD_KEY_REVOKED, SHIELD_KEY_EXPIRED, SCOPE_DENIED, ORIGIN_NOT_ALLOWED, POOL_MISMATCH, SHIELD_REGISTRY_UNAVAILABLE, SHIELD_REGISTRY_STALE, SHIELD_ENV_MISCONFIGURED, PAYMENT_ENV_MISMATCH, SIGNING_UNAVAILABLE, LEGACY_API_DISABLED, CAPTURED_PROOF_UNAVAILABLE, NOT_FOUND, INVALID_SHIELD_KEY, INVALID_SHIPPING_ADDRESS, INVALID_EMAIL, INVALID_ORDER, MISSING_PK, UNKNOWN_PK, PK_POOL_MISMATCH, RATE_LIMITED, TEMPORARILY_LOCKED, INVALID_PHONE, NO_METHOD_FOR_AMOUNT, NOT_SUCCEEDED, ALREADY_COMPLETED, AMOUNT_MISMATCH, WALLET_REQUIRED, STRIPE_ERROR, SELECT_FAILED, NO_ACTIVE, NO_POOL

SignedEnvelope

Body thành công v1 trên /v1/capture_order và /v1/stripe/complete (envelope builder v1 dùng chung). Chỉ mang bằng chứng Ed25519 — không bao giờ có các field legacy signature/signed_fields/ payload_signature. Xác minh sig dựa trên các byte chính xác của signed_payload (một chuỗi JSON, không phải object — không re-serialize nó) dùng public key cho kid lấy từ /v1/keys.

trườngkiểumô tả
errorbooleanbắt buộc
dataobjectbắt buộc

Lặp lại hình dạng legacy cho endpoint này (kết quả PayPal OrdersCaptureRequest, hoặc signed_fields dạng flat của Stripe) — chỉ mang tính thông tin; bằng chứng là signed_payload+sig, không phải field này.

signed_payloadstringbắt buộc

chuỗi JSON chính xác đã được ký (xác minh dựa trên các byte chính xác này)

sigstringbắt buộc

chữ ký Ed25519 base64url trên signed_payload

kidstringbắt buộc

key id — dùng nó để tra JWK khớp trên /v1/keys

algstringbắt buộc
vintegerbắt buộc
contactobjecttùy chọn

Chỉ Stripe /v1/stripe/complete — thông tin liên hệ billing/shipping KHÔNG ĐƯỢC KÝ thu thập tại wallet sheet. Chỉ mang tính thông tin, không bao giờ là một phần của bằng chứng đã xác minh; không tin tưởng cho các quyết định fraud/compliance.

PaypalCaptureV1Payload

Hình dạng đã parse của signed_payload cho /v1/capture_order (các field extra của PayPal capture signed-payload builder cộng với envelope builder v1 dùng chung). Mọi field dưới đây đều được ký — không field nào có thể bị thay đổi mà không làm sig không hợp lệ.

trườngkiểumô tả
order_idstringbắt buộc
capture_idstringbắt buộc
statusstringbắt buộc

trạng thái capture của PayPal, ví dụ COMPLETED

amountstringbắt buộc

chuỗi decimal, ví dụ "19.99"

currencystringbắt buộc
invoice_idstringbắt buộc

id đơn hàng của store

reference_idstringbắt buộc

'' khi purchase_unit của PayPal không mang giá trị nào (luôn là string, không bao giờ null). DO CLIENT KHAI BÁO lúc tạo order, nằm trong tập được ký chỉ để chống giả mạo; không được xác minh độc lập ở phía server, nên coi là CHỈ MANG TÍNH THÔNG TIN trừ khi bạn tự đặt nó và assert lại.

payee_merchant_idstringbắt buộc

'' khi không có (payee của PayPal được ưu tiên hơn merchant id fallback đã cấu hình của shield)

shieldstringbắt buộc

shield domain đã xử lý capture

iatintegerbắt buộc

unix seconds

typstringbắt buộc
vintegerbắt buộc
partner_idstringbắt buộc

ranh giới bảo mật — phải khớp partner id của chính caller

key_idstringbắt buộc

ranh giới bảo mật — phải là một trong các key id được caller cho phép

envstringbắt buộc

ranh giới bảo mật — một key shpk_test_… tương ứng với 'sandbox' ở đây

store_domainstring | nullbắt buộc

DO CLIENT KHAI BÁO, KHÔNG chuẩn hóa ở phía server — chỉ mang tính thông tin/audit, không bao giờ là một phần của ranh giới tin cậy (không ràng buộc việc xác minh vào giá trị này).

StripeAddress

Hình dạng con địa chỉ bưu chính bên trong Contact. KHÔNG ĐƯỢC KÝ (chỉ để hiển thị). Phản chiếu object address gốc của Stripe; bất kỳ field nào có thể là null khi Stripe không thu thập nó.

trườngkiểumô tả
line1string | nulltùy chọn
line2string | nulltùy chọn
citystring | nulltùy chọn
statestring | nulltùy chọn
postal_codestring | nulltùy chọn
countrystring | nulltùy chọn

Contact

Thông tin liên hệ/giao hàng của người mua trả về cùng một envelope v1 Stripe. KHÔNG ĐƯỢC KÝ — KHÔNG phải một phần của bằng chứng đã xác minh, không dùng cho các quyết định fraud/compliance. name/address ưu tiên chi tiết SHIPPING, fallback về billing; email/phone ưu tiên BILLING (email fallback về receipt_email). Trên một lần replay v1, wallet_type có thể fallback về giá trị do client cung cấp trong request — coi đó là gợi ý từ client, không phải giá trị đáng tin, trên các lần gọi replay.

trườngkiểumô tả
namestring | nullbắt buộc
addressmột trongbắt buộc

null khi Stripe không có cả shipping và billing address trên PaymentIntent

emailstring | nullbắt buộc
phonestring | nullbắt buộc
wallet_typestringbắt buộc

nhãn wallet đáng tin suy ra từ lần charge (ví dụ apple_pay/google_pay); '' khi chưa biết; gợi ý từ client khi replay — xem mô tả ở trên

StripeCompleteV1Payload

Hình dạng đã parse của signed_payload cho /v1/stripe/complete (các field dạng flat, cộng với mọi key meta_*). Mọi properties dưới đây cộng với mọi key meta_* đều ĐƯỢC KÝ (chống giả mạo); xác minh sig trên signed_payload chứng minh không field nào bị thay đổi sau khi shield tạo ra envelope này. RANH GIỚI BẢO MẬT (những gì một verifier PHẢI assert): partner_id + key_id (∈ các key id được bạn cho phép) + env + invoice_id + amount_received + id (chống replay — từ chối nếu đã settle) + status === 'succeeded' + iat trong khoảng [-600s, +300s] so với hiện tại. store, store_domain, reference_id và mọi key meta_* đều DO CLIENT KHAI BÁO lúc create-time (SDK/caller cung cấp chúng; server chỉ flatten và ký để chống giả mạo, không bao giờ xác minh độc lập nội dung) — CHỈ MANG TÍNH THÔNG TIN/audit/hiển thị, không bao giờ dùng chúng cho quyết định ràng buộc ở trên.

trườngkiểumô tả
idstringbắt buộc

Stripe PaymentIntent id (pi_…) — RANH GIỚI BẢO MẬT: key chống replay của bạn, từ chối nếu đã settle

amount_receivedintegerbắt buộc

RANH GIỚI BẢO MẬT — số nguyên cent, chỉ USD (Stripe v1 chỉ hỗ trợ USD; không có field currency). Phải bằng tổng đơn hàng của bạn tính bằng cent.

statusstringbắt buộc

RANH GIỚI BẢO MẬT — phải chính xác là 'succeeded' (complete() chỉ ký một PI đã succeeded)

storestringbắt buộc

DO CLIENT KHAI BÁO — location.hostname của trang store do SDK gửi lúc create-intent (chữ thường, không có port, giữ www. nếu có; KHÔNG chuẩn hóa ở phía server). CHỈ MANG TÍNH THÔNG TIN, không bao giờ là một phần của ranh giới tin cậy.

invoice_idstringbắt buộc

RANH GIỚI BẢO MẬT — id đơn hàng store của bạn, ràng buộc-kiểm tra giá trị này với đơn hàng của bạn

reference_idstringbắt buộc

'' khi không có. DO CLIENT KHAI BÁO lúc create-time — CHỈ MANG TÍNH THÔNG TIN trừ khi bạn tự đặt nó và assert lại

ship_namestringbắt buộc

'' khi không có

ship_phonestringbắt buộc

'' khi không có

ship_line1stringbắt buộc

'' khi không có

ship_line2stringbắt buộc

'' khi không có

ship_citystringbắt buộc

'' khi không có

ship_statestringbắt buộc

'' khi không có

ship_postalstringbắt buộc

'' khi không có

ship_countrystringbắt buộc

'' khi không có

bill_namestringbắt buộc

'' khi không có

bill_emailstringbắt buộc

'' khi không có

bill_phonestringbắt buộc

'' khi không có

bill_line1stringbắt buộc

'' khi không có

bill_line2stringbắt buộc

'' khi không có

bill_citystringbắt buộc

'' khi không có

bill_statestringbắt buộc

'' khi không có

bill_postalstringbắt buộc

'' khi không có

bill_countrystringbắt buộc

'' khi không có

typstringbắt buộc
vintegerbắt buộc
partner_idstringbắt buộc

RANH GIỚI BẢO MẬT — phải khớp partner id của chính caller

key_idstringbắt buộc

RANH GIỚI BẢO MẬT — phải là một trong các key id được caller cho phép

envstringbắt buộc

RANH GIỚI BẢO MẬT — một key shpk_test_… tương ứng với 'sandbox' ở đây

store_domainstring | nullbắt buộc

DO CLIENT KHAI BÁO — location.hostname của trang đã gọi /v1/stripe/complete (completeBody.store_domain || null); '' trở thành null. Có thể khác store trên một luồng redirect-return (trang return, không phải trang checkout gốc). CHỈ MANG TÍNH THÔNG TIN, KHÔNG phải một phần của ranh giới tin cậy.

iatintegerbắt buộc

RANH GIỚI BẢO MẬT — unix seconds; verifier phải ép buộc khoảng [-600s, +300s]

Jwks

Tập JWK OKP Ed25519 theo RFC 8037 phục vụ bởi /v1/keys.

trườngkiểumô tả
keysarraybắt buộc

mảng gồm:

  • kty string bắt buộc
  • crv string bắt buộc
  • x string bắt buộc

    public key 32 byte dạng base64url

  • kid string bắt buộc
  • alg string bắt buộc
  • use string bắt buộc