remp / crm-wallet-pay-module
CRM 钱包支付模块(支持 Apple Pay 和 Google Pay)
Requires
- php: ^8.1
README
此模块提供将 Apple Pay 和 Google Pay 支付网关集成到销售漏斗中的功能。
目前该模块支持使用 Tatrabanka 提供商的 网关 实现。此提供商目前不支持周期性支付。
安装
要安装模块,请运行
composer require remp/crm-wallet-pay-module
在您的 app/config/config.neon
文件中启用已安装的扩展
extensions: # ... - Crm\WalletPayModule\DI\WalletPayModuleExtension
要使模块功能在销售漏斗中可用,请在应用程序根目录中运行此命令以复制资源(或运行 composer install
,这将同时安装资源)
# run in CRM root folder
php bin/command.php application:install_assets
集成
Apple Pay 按钮
配置
在 CRM 设置中(crm.press/admin/config-admin/
)的 支付 部分,配置 Apple Pay 选项。这些包括 Apple Pay 商户 ID 证书和密钥的路径(如果加密,包括密码)。有关更多信息,请参阅有关如何 设置 Apple Pay 的官方文档。
要求
Apple Pay 需要 HTTPS 网页,并具有有效的 TLS 证书。
在销售漏斗中使用
首先,在 CRM 管理员的销售漏斗设置中,将“ApplePay 钱包”支付网关添加到允许的网关列表中。
接下来,在销售漏斗 <head>
标签中包含 WalletPay JS 库(如果尚未包含)
<script src="/layouts/wallet-pay-module/js/wallet-pay.js"></script>
要显示按钮本身,请将以下代码片段插入您的 HTML 文档中的某个位置。注意 hidden
类 - 按钮最初应隐藏,在我们检查 Apple Pay 可用性之前。
<apple-pay-button buttonstyle="black" type="buy" locale="sk_SK" class="hidden" style="--apple-pay-button-width: 100%; --apple-pay-button-height: 40px; --apple-pay-button-border-radius: 5px; --apple-pay-button-padding: 5px 0px;"> </apple-pay-button>
接下来,确保当前浏览器上下文中可使用 Apple Pay
// MERCHANT_ID is ID assigned in the Apple Pay settings RempWalletPay.checkApplePayAvailability(MERCHANT_ID, function () { // called only if button should be displayed // remove 'hidden' class to display the button document.getElementsByTagName('apple-pay-button')[0].classList.remove('hidden'); });
要初始化按钮,运行 initApplePayButton
。最基本的配置
const config = { totalPrice: '0.10', merchantName: 'Example Merchant s.r.o', productName: 'Example Product Name', // Function to retrieve sales funnel payment form data (will be sent together with Apple Pay token to backend). // Library takes care of response processing and redirect. salesFunnelFormData: () => { return new FormData(document.getElementById('form')); }, // Optional, function returning true/false depending on whether Apple Pay execution should continue after clicking on the button. isValid: () => true, }; RempWalletPay.initApplePayButton(config);
或者,您可以提供 onSuccess
回调,该回调允许您处理在支付期间发布的 Apple Pay 令牌
const config = { totalPrice: '0.10', merchantName: 'Example Merchant s.r.o', productName: 'Example Product Name', // Callback, called after user confirms the payment in the Apple modal (e.g. by fingerprint). // It receives two arguments: // - token - Apple Pay token // - completePaymentCallback - callback, should be called after backend (un/successfully) ackowledges the payment onSuccess: (token, completePaymentCallback) => { var fd = new FormData(document.getElementById('form')); fd.append('apple_pay_token', token); fetch('/sales-funnel/sales-funnel-frontend/submit', { method: 'POST', body: fd, }) .then(response => response.json()) .then(data => { completePaymentCallback(true); window.top.location.href = data.apple_pay.redirect_url; // redirect to success page }) .catch(e => completePaymentCallback(false)); }, // optional, function returning true/false depending on whether Apple Pay execution should continue after clicking on the Pay button. isValid: () => some_check_to_see_if_payment_form_is_valid(), }; RempWalletPay.initApplePayButton(config);
支付按钮更新
要更新按钮的价格或产品名称,请调用
RempWalletPay.updateApplePayButton({ totalPrice: '0.20', // new price // productName: 'new product name', });
Google Pay
配置
要设置 Google Pay 并获取所需的凭据,请遵循有关 Google Pay for web 的官方文档。
要求
Google Pay 需要 HTTPS 网页,并具有有效的 TLS 证书。
在销售漏斗中使用
首先,在 CRM 管理员的销售漏斗设置中,将“GooglePay 钱包”支付网关添加到允许的网关列表中。
接下来,在销售漏斗 <head>
标签中包含 WalletPay JS 库(如果尚未包含)
<script src="/layouts/wallet-pay-module/js/wallet-pay.js"></script>
要显示按钮本身,请将以下代码片段插入您的 HTML 文档中的某个位置。
<google-pay-button environment="PRODUCTION" button-locale="sk" button-color="white" button-size-mode="fill" style="width:100%"> </google-pay-button>
按钮的所有属性在 GitHub 文档 中描述。
要初始化按钮,运行 initGooglePayButton
。最基本的配置
const config = { // price shown to user totalPrice: '0.10', // merchantId is one of the credentials obtain during configuration merchantId: '1234567890', // some merchant name to show to user merchantName: 'Example merchant', // Function to retrieve sales funnel payment form data (will be sent together with Google Pay token to backend). // Library takes care of response processing and redirect. salesFunnelFormData: () => { return new FormData(document.getElementById('form')); }, // Optional, function returning true/false depending on whether Google Pay execution should continue after clicking on the button. isValid: () => true, // Optional, callback function to show progress during the payment inProgress: (promise) => { console.log("Google payment starts"); // here, display some animation promise.then(() => { console.log("Google payment starts"); // here, stop the animation }); } }; RempWalletPay.initGooglePayButton(config);
或者,提供 onSuccess
回调,该回调允许您处理在支付期间发布的 Google Pay 令牌并放置 3DS 对话框 HTML 代码的位置
const config = { // price shown to user totalPrice: '0.10', // merchantId is one of the credentials obtain during configuration merchantId: '1234567890', // some merchant name to show to user merchantName: 'Example merchant', // Callback, called after user confirms the payment in the Google Pay dialog. // Argument: // - token - Google Pay token onSuccess: (token) => { var fd = new FormData(document.getElementById('form')); fd.append('google_pay_token', token); fetch('/sales-funnel/sales-funnel-frontend/submit', { method: 'POST', body: fd, }) .then(response => response.json()) .then(data => { // if 'tds_html' attribute is present, 3DS is required if (data.google_pay.tds_html) { // helper function to display 3DS html in an iframe modal RempWalletPay.show3ds(data.google_pay.tds_html); } else { // redirect to success page (no 3DS requirement to finish the payment) window.top.location.href = data.google_pay.redirect_url; } }); }, // Optional, function returning true/false depending on whether Google Pay execution should continue after clicking on the button. isValid: () => true, // Optional, callback function to show progress during the payment inProgress: (promise) => { console.log("Google payment starts"); // here, display some animation promise.then(() => { console.log("Google payment starts"); // here, stop the animation }); } }; RempWalletPay.initGooglePayButton(config);
支付按钮更新
要更新按钮的价格,请调用
RempWalletPay.updateGooglePayButton({ totalPrice: '0.20', // new price });
扩展
如果您想使用自己的网关提供商(而不是Tatrabanka),您可以扩展此模块以包含自己的实现。请注意,此模块不支持直接钱包支付。
首先,您需要通过提供Google/Apple支付接口的实现来实施集成。
Crm\WalletPayModule\Model\GooglePayWalletInterface
Crm\WalletPayModule\Model\ApplePayWalletInterface
准备好后,请在您的config.neon
文件中注册它们,并覆盖此模块提供的默认实现。
services: applePayWallet: Crm\FooModule\Model\YourProviderApplePayWallet googlePayWallet: Crm\FooModule\Model\YourProviderGooglePayWallet
API文档
所有示例都使用http://crm.press
作为基础域名。请在执行示例之前将主机更改为您使用的域名。
API响应可以包含以下HTTP状态码
如果可能,响应将包括application/json
编码的有效负载,其中包含进一步解释错误的消息。
GET /api/v1/apple-pay/merchant-validation
验证Apple Pay商户身份的API调用。
参数
示例
curl -v –X GET http://crm.press/api/v1/apple-pay/merchant-identity?url=VALIDATION_URL
响应
{ "epochTimestamp": 1655206603128, "expiresAt": 1655210203128, "merchantSessionIdentifier": "...", "nonce": "SOME_NONCE", "merchantIdentifier": "...", "domainName": "crm.press", "displayName": "CRM", "signature": "SIGNATURE_DATA_BASE64", "operationalAnalyticsIdentifier": "DEVEL CRM:SOME_ID", "retries": 0, "pspId": "..." }
响应可能不同,因为它包含由Apple提供的商户验证服务返回的数据。