# Drop-in Web ## 介绍 嵌入式收银台支持将 PayKKa 的收银台支付组件嵌入您的结账页面,用于收集消费者的付款信息。 您可以通过 PayKKa Checkout UI 组件创建自己的结账流程,消费者输入的付款信息仅在组件内传递,可以降低您的 PCI-DSS 合规性成本 接入 Component/Drop-in 需要提供您的域名解除跨域限制 ## 支持的支付方式 - Visa - MasterCard - JCB - American Express - Discover - Diners Club - Apple Pay - Google Pay - WechatPay - Alipay+ - GCash - Maya (Paymaya) - ShopeePay - GrabPay - Zalopay - VietQR ## 支付流程 Description of image 1. 客户访问您的结账页面,输入客户发货和账单等信息,点击支付按钮 2. 您由服务器发起支付请求用于创建收银台,您将得到收银台ID(session_id)用于后续加载收银台页面 3. 您使用收银台ID(`session_id`)和Client key(`client_key`)在当前页面内加载嵌入式收银台页面 4. 嵌入式收银台页面将动态显示支持的支付方式,客户选择支付方式后,点击支付按钮 5. 提交支付后,我们将处理所有可能的额外操作,如 3DS 认证或者第三方重定向页面 6. 支付处理完成后,将触发组件回调函数,您可以在此处处理支付结果(组件回调函数支持多种回调事件,建议至少接入onSuccess、onExpired、onError事件) 7. 您的webhook地址将收到支付结果通知(建议您接入交易查询获取支付结果) ## 接入流程 1. 获取您的交易密钥 2. 获取您的 Client key 3. 准备接入的通知地址 webhook ,提供到请求参数中或者设置在后台,将会在关键的支付节点发送通知给商户 4. 准备接入的跳转地址,提供到请求参数中,将会在收银台支付完成后跳转 5. 发起请求: [Create Session](/zh-hans/payments/apis/payments/openapi/收银台/session-opl_1)接口创建收银台,返回收银台页面 URL 6. 接入前端组件方式见 [PayKKa Checkout UI Component](/zh-hans/payments/docs/developer-resources/checkout-ui-component) 7. 商户可以接入[Query Session](/zh-hans/payments/apis/payments/openapi/收银台/session-query-opl_2)接口获取收银台结果,或者可以直接接入[Query Transaction](/zh-hans/payments/apis/payments/openapi/交易/payments-query-opl_1)接口获取订单结果(若最终无结果表示消费者未发起交易) PayKKa 的收银台(标识:session_id)代表页面形式的支付意向,最终的支付结果由交易(标识: `order_id` )结果决定,因此您需要关注订单的最终状态以确定支付结果 收银台查询: 用于查询收银台的状态和支付结果,若消费者未发起支付,则不会产生交易订单 交易查询: 用于查询交易订单的支付结果,订单终态后会通过 webhook 通知 组件默认样式 Description of image Description of image Description of image ### 创建收银台 当客户准备支付时,发送服务端请求可以创建一个Session和对应链接,通过Session来发起支付请求 请求示例 [Create Session](/zh-hans/payments/apis/payments/openapi/收银台/session-opl_1) ```json { "merchant_id": "18356675194960", "payment_type": "PURCHASE", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC", "trans_id": "m3246749195217", "expire_time": "2025-05-05T17:17:24+08:00", "session_mode": "DROP_IN", # 收银台模式,HOSTED: 托管, DROP_IN: 嵌入, COMPONENT: 组件 "display_locale": "fr-FR", "currency": "HKD", "amount": "800", "return_url": "https://url", "payment": { "store_payment_method": true, # 是否存储卡信息并令牌化,将得到token;true: 存储, false: 不存储 "token_usage": "CARD_ON_FILE" "shopper_reference": "854f5baaf0a735139c583c4cea14d14c" }, "goods": [ // 商品信息 ], "bill": { // 账单信息 }, "shipping": { // 收货信息, 实物贸易必填 }, "customer": { // 消费者/客户信息 } } ``` 响应示例 ```json { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "session_id": "CS208760010022288125", "session_mode": "DROP_IN", "status": "PROCESSING", "currency": "HKD", "amount": "800", "expire_time": "2025-05-05T17:17:24+08:00", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC" } } ``` ### 添加 Drop-in 可以安装 PayKKa Checkout UI npm 包,或者通过 CDN 的方式嵌入到 HTML 中: npm(推荐) 安装 `@paykka/card-checkout-ui`: npm ```bash npm i @paykka/card-checkout-ui ``` pnpm ```bash pnpm i @paykka/card-checkout-ui ``` yarn ```bash yarn add @paykka/card-checkout-ui ``` 为了正常的展示组件,需要全局引入样式: ```typescript import '@paykka/card-checkout-ui/style.css' ``` CDN 引入 通过 CDN 链接在 HTML 中引入 PayKKa Checkout UI 样式和脚本,推荐使用对应区域的 CDN 链接: 欧洲 ```html ``` 香港 ```html ``` #### 创建 PayKKaCheckout 实例 ##### PayKKaCheckout 构建参数 创建 `PayKKaCheckout` 实例时可传递参数及事件如下: 必填参数用 * 标识。 | **名称** | **说明** | **类型** | | --- | --- | --- | | *sessionId | 收银台 ID,用来创建收银台。 | `string` | | *clientKey | 客户端密钥。 | `string` | | *env | 环境配置。- `eu` 为欧洲商户。 - `hk` 为香港商户。 - `sandbox` 为沙箱环境商户。 | | | locale | 收银台文案展示语言。- 不传则获取浏览器语言,若浏览器语言不在支持范围内,则默认使用 `en-GB`。 - 目前支持如下 11 种国际化语言,按照 IETF BCP 47 格式展示: - `de-DE`:德语(德国) - `en-GB`:英语(英国) - `es-ES`:西班牙语(西班牙) - `fr-FR`:法语(法国) - `ja-JP`:日语(日本) - `ko-KR`:韩语(韩国) - `pt-PT`:葡萄牙语(葡萄牙) - `ru-RU`:俄语(俄罗斯) - `zh-CN`:中文(中国) - `zh-HK`:中文(香港) - `zh-TW`:中文(台湾) | `string` | | hidePaymentButton | 是否隐藏支付按钮,默认为 `false`。- 若隐藏支付按钮,则需要手动调用组件的 `payment` 方法进行支付。 | `boolean` | | threeDSFrame | 3DS 配置对象,包含如下参数:- `modalWidth`:3DS 弹窗宽度,不传默认自适应。传 `number` 单位为 `px`, 传 `string` 可自定义单位,最小宽度为 `350px`。 - `modalHeight`:3DS 弹窗高度,不传默认自适应。传 `number` 单位为 `px`, 传 `string` 可自定义单位,最小高度为 `500px`。 | `ThreeDSFrameConfig` | | onPaymentMethodsReady | 收银台已经获取可用支付方式时触发。- `methods` 为可用支付方式列表。 - 若返回空数组,则表示无可用支付方式,且组件不会展示。 - 收银台状态为成功或过期时,同样会返回空数组。 - 目前支持如下 8 种支付方式: - `APPLE_PAY`:Apple Pay - `GOOGLE_PAY`:Google Pay - `VISA`:Visa - `MASTER_CARD`:Master Card - `JCB`:JCB - `AMEX`:AMEX - `DINERS_CLUB`:Diners Club - `DISCOVER`:Discover | `(methods: PaymentMethod[]) => void` | | onInitError | 收银台初始化异常时触发。- `error` 为 `PayKKaError` 实例,通常包含以下属性: - `type`:错误类型。 - `message`:错误信息。 - `code`:错误码,在发生接口错误时,会返回具体的[错误码](#%E9%94%99%E8%AF%AF%E7%A0%81)。 - 收银台状态为成功或过期后再次初始化,同样会触发该回调。 | `(error: PayKKaError) => void` | | onSubmit | 提交表单时触发的**全局事件**。- `formValidateError` 为表单校验错误信息。 - 可被 Component 中定义的同名事件所覆盖。 | `(formValidateError?: Record) => void` | | onSuccess | 支付成功后触发的**全局事件**。- `returnUrl` 为支付完成后跳转的链接。 - 可被 Component 中定义的同名事件所覆盖。 | `({returnUrl?: string}) => void` | | onTimeout | 支付超时后触发的**全局事件**。- 用户可重新提交表单进行支付。 - 可被 Component 中定义的同名事件所覆盖。 | `() => void` | | onExpired | 会话过期或失效后触发的**全局事件**,或者支付成功后再次调起组件也会触发。- 可被 Component 中定义的同名事件所覆盖。 | `() => void` | | onError | 支付失败后触发的**全局事件**。- `error` 为 `PayKKaError` 实例,通常包含以下属性: - `type`:错误类型。 - `message`:错误信息。 - `code`:错误码,在发生接口错误时,会返回具体的[错误码](#%E9%94%99%E8%AF%AF%E7%A0%81)。 - 用户可重新提交表单进行支付。 - 可被 Component 中定义的同名事件所覆盖。 | `(error: PayKKaError) => void` | 下面是使用示例: npm ```javascript import { PayKKaCheckout } from '@paykka/card-checkout-ui' // 创建 PayKKaCheckout 实例 const paykkaCheckout = new PayKKaCheckout({ sessionId: 'xxx', clientKey: 'xxx', env: 'eu', locale: 'en-GB', hidePaymentButton: false, threeDSFrame: { modalWidth: '350px', modalHeight: '500px', }, onPaymentMethodsReady: (methods) => { console.log('支持的支付方式', methods) }, onInitError: (error) => { console.log('初始化错误', error) }, onSubmit: (formValidateError) => { console.log('提交表单全局事件', formValidateError) }, onSuccess: ({ returnUrl }) => { console.log('支付成功全局事件', returnUrl) }, onTimeout: () => { console.log('支付超时全局事件') }, onExpired: () => { console.log('会话过期或失效全局事件') }, onError: () => { console.log('支付失败全局事件') } }) ``` CDN ```javascript const { PayKKaCheckout } = PayKKaCardCheckoutUI // 创建 PayKKaCheckout 实例 const paykkaCheckout = new PayKKaCheckout({ sessionId: 'xxx', clientKey: 'xxx', env: 'eu', locale: 'en-GB', hidePaymentButton: false, threeDSFrame: { modalWidth: '350px', modalHeight: '500px', }, onPaymentMethodsReady: (methods) => { console.log('支持的支付方式', methods) }, onInitError: (error) => { console.log('初始化错误', error) }, onSubmit: (formValidateError) => { console.log('提交表单全局事件', formValidateError) }, onSuccess: ({ returnUrl }) => { console.log('支付成功全局事件', returnUrl) }, onTimeout: () => { console.log('支付超时全局事件') }, onExpired: () => { console.log('会话过期或失效全局事件') }, onError: () => { console.log('支付失败全局事件') } }) ``` #### 创建 Drop-in 实例 ##### Drop-in 构建参数 创建 `DropIn` 实例时可传递参数及事件如下: | 名称 | 说明 | 类型 | | --- | --- | --- | | paymentMethods | 构建各种支付方式的参数,最终展示的支付方式由创建收银台请求返回结果决定,而不是由该参数决定,包含如下属性:- `card`:Card 组件的构建参数。 - `applePay`:ApplePay 组件的构建参数。 - `googlePay`:GooglePay 组建的构建参数。 | `PaymentMethodsConfig` | | layout | 布局,`tabs` 表示使用 tab 切换式布局,目前暂不支持 accordion(手风琴)布局。 | `'tabs'` | | onSubmit | 提交表单时触发的事件。- `formValidateError` 为表单校验错误信息。 | `(formValidateError?: Record) => void` | | onSuccess | 支付成功后触发的事件。- `returnUrl` 为支付完成后跳转的链接。 | `({returnUrl?: string}) => void` | | onTimeout | 支付超时后触发的事件。- 用户可重新提交表单进行支付。 | `() => void` | | onExpired | 会话过期或失效后触发的事件,或者支付成功后再次调起组件也会触发。 | `() => void` | | onError | 支付失败后触发的事件。- `error` 为 `PayKKaError` 实例,通常包含以下属性: - `type`:错误类型。 - `message`:错误信息。 - `code`:错误码,在发生接口错误时,会返回具体的[错误码](#%E9%94%99%E8%AF%AF%E7%A0%81)。 - 用户可重新提交表单进行支付。 | `(error: PayKKaError) => void` | ##### 步骤 1: 创建 DOM 元素 在您的收银台页面创建一个 DOM 元素,该元素将用于呈现 Drop-in。 ```html
``` 强烈建议您不要在 iframe 元素内创建该 DOM 元素,否则可能导致收银台无法正常使用。 ##### 步骤 2: 引入 DropIn 并构建实例 ```javascript import { PayKKaCheckout, DropIn } from '@paykka/card-checkout-ui' // 此处省略创建 PayKKaCheckout 实例步骤 const checkoutDropIn = paykkaCheckout.create(DropIn, { paymentMethods: { card: { /** Card 组件的构建参数 */ }, applePay: { /** :ApplePay 组件的构建参数 */ }, googlePay: { /** :GooglePay 组件的构建参数 */ } }, layout: 'tabs', onSubmit: formValidateError => { console.log('提交表单事件', formValidateError) }, onSuccess: ({ returnUrl }) => { console.log('支付成功事件', returnUrl) }, onTimeout: () => { console.log('支付超时事件') }, onExpired: () => { console.log('会话过期或失效事件') }, onError: () => { console.log('支付失败事件') } }) ``` ##### 步骤 3: 挂载 Component ```javascript const container = document.querySelector('#drop-in-container') checkoutDropIn.mount(container) ``` 如果您使用的是如 Angular、Vue、React 等 JavaScript 框架,请确保 DOM 已渲染完成再进行挂载,并且不要重新渲染元素。 ### 收银台查询 查询收银台状态,通过收银台ID(`session_id`)查询 请求示例 [Query Session](/zh-hans/payments/apis/payments/openapi/收银台/session-query-opl_2) ```json { "merchant_id": "18356675194960", "trans_id": "m3246749195217", # trans_id/session_id二选一 "session_id": "CS208760010022288125" } ``` 响应示例 处理中 ```json { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "session_id": "CS208760010022288125", "session_mode": "DROP_IN", "status": "PROCESSING", "amount": "800", "currency": "HKD", "expire_time": "2025-05-05T17:17:24+08:00", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC" } } ``` 成功 ```json { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "session_id": "CS208760010022288125", "session_mode": "DROP_IN", "status": "SUCCESS", # 收银台状态 "order_status": "SUCCESS", # 交易状态 "error_code": "0000", # 交易错误码 "error_description": "request success", "order_id": "GW208760010022288125", # 交易订单号 "amount": "800", "currency": "HKD", "expire_time": "2025-05-05T17:17:24+08:00", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC" } } ``` 过期 ```json 超期未支付 { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "session_id": "CS208760010022288125", "session_mode": "DROP_IN", "status": "EXPIRED", # 收银台状态 "amount": "800", "currency": "HKD", "expire_time": "2025-05-05T17:17:24+08:00" } } 支付失败 { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "session_id": "CS208760010022288125", "session_mode": "DROP_IN", "status": "EXPIRED", # 收银台状态 "amount": "800", "currency": "HKD", "order_status": "FAILURE", # 交易状态 "error_code": "0000", # 交易错误码 "error_description": "request success", "order_id": "GW208760010022288125", # 交易订单号 "expire_time": "2025-05-05T17:17:24+08:00" } } ``` ### 交易查询 查询交易状态,通过交易ID(`order_id`)查询 请求示例 [Query Transaction](/zh-hans/payments/apis/payments/openapi/交易/payments-query-opl_1) ```json { "merchant_id": "18356675194960", "trans_id": "m3246749195217", # session_id/order_id/trans_id三选一 "session_id": "CS208760010022288125", "order_id": "GW208760010022288125" } ``` 响应示例 ```json { "ret_code": "000000", "ret_msg": "Success", "data": { "merchant_id": "18356675194960", "trans_id": "m3246749195217", "order_id": "GW208760010022288125", "session_id": "CS208760010022288125", "status": "SUCCESS", # 交易状态 "error_code": "0000", # 交易错误码 "error_description": "request success", "amount": "800", "currency": "HKD", "pay_finish_time": "2025-05-05T17:17:24+08:00" } } ``` ## 消费与循环 如果您的付款要求按照一定周期(如每月、每年或自定义时间间隔)从客户的银行卡或电子钱包中重复扣款,无需客户每次手动授权,您可以使用 PayKKa 的循环支付功能。 ### 集成方式 1. 目前 PayKKa 支持的循环支付需要由商户定期发起 2. 对于首次循环支付,需要 PayKKa 存储持卡人的卡信息,后续的循环支付只需要提供持卡人的 token 即可 3. 对于后续的循环支付,只需要提供持卡人的 token 即可,无需重复提供卡信息 首次循环请求示例 [Create Session](/zh-hans/payments/apis/payments/openapi/收银台/session-opl_1) ```json { "merchant_id": "18356675194960", "payment_type": "RECURRING", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC", "trans_id": "m3246749195217", "expire_time": "2025-05-05T17:17:24+08:00", "session_mode": "COMPONENT", "display_locale": "fr-FR", "currency": "HKD", "amount": "800", "return_url": "https://url", "mit": false, "payment": { "store_payment_method": true, "token_usage": "SUBSCRIPTION", "shopper_reference": "854f5baaf0a735139c583c4cea14d14c" }, "goods": [ // 商品信息 ], "bill": { // 账单信息 }, "shipping": { // 收货信息, 实物贸易必填 }, "customer": { // 消费者/客户信息 } } ``` 后续循环请求示例 [Initiate Transaction](/zh-hans/payments/apis/payments/openapi/交易/payments-opl_1) ```json { "merchant_id": "18356675194960", "payment_type": "RECURRING", "authorisation_type": "FINAL_AUTH", "capture_method": "AUTOMATIC", "trans_id": "m3246749195217", "currency": "HKD", "amount": "800", "mit": true, "recurring_agreement_id": "RA4264524535435435", "payment": { "payment_method": "BANKCARD", "shopper_reference": "558b5cb1b8cbcc8496062155c69cf2ab", "token": "TK20231435132143229" } } ``` ## 3DS 处理 收银台产品无需您处理 3DS 认证,PayKKa 将全自动对支付安全进行智能化检测和处理,您只需关注支付结果即可 ## 有效期 收银台过期时间最大为 24 小时,过期后将无法继续支付;Drop-in 组件将收到回调事件 `onExpired`,您可以在该事件中提示用户支付已过期,并引导用户重新发起支付 若过期未发起支付,将不会有通知,查询收银台状态将得到 `status=EXPIRED`,查询交易状态将得到 `ret_msg=the order doesn't exist` ## 错误码 参见 [交易错误码](/zh-hans/payments/docs/developer-resources/transanction-error-code) ## 结果通知 参考 [Webhook](/zh-hans/payments/docs/developer-resources/webhook)