Version Description
- 2022-05-04 =
- New - Upgrade the payment form on checkout to use the latest Square Web Payments SDK. PR#668
- Fix - Compatibility issues with WordPress 6.1.0. PR#715
- Fix - Sync issues caused by product variations having an empty SKU and incorrectly being set to the variable product (parent product) SKU value. PR#764
- Update - Remove admin notice warning of v3.0.0 release. PR#744
- Dev - Product importing is now handled by Action Scheduler. PR#698
- Dev - Syncing is now handled by Action Scheduler. PR#699
- Dev - Manual Sync is now handled by Action Scheduler. PR#710
- Dev - Upgrade Action Scheduler to 3.4.0. PR#762
- Dev - Updated Square Connect to Square SDK v 15.0.0. PR#673 PR#670 PR#668 PR#664 PR#659 PR#657
- Dev - Remove SkyVerge framework. PR#690 PR#689 PR#688 PR#687 PR#684 PR#683 PR#681 PR#678
Download this release
Release Info
Developer | automattic |
Plugin | WooCommerce Square |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.9.1 to 3.0.0
- assets/css/admin/wc-square-payment-gateway-admin-order.min.css +1 -0
- assets/css/admin/wc-square-payment-gateway-token-editor.min.css +1 -0
- assets/css/frontend/wc-square-digital-wallet.min.css +1 -1
- assets/css/frontend/wc-square-payment-gateway-my-payment-methods.min.css +1 -0
- assets/css/frontend/wc-square-payment-gateway-payment-form.min.css +1 -0
- vendor/skyverge/wc-plugin-framework/tests/_archive/integration/plugin.php → assets/css/mixins.min.css +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/assets → assets}/css/mixins.scss +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amazon.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amazon.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amex.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amex.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cartebleue.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cartebleue.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-invalid.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-invalid.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-plain.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-plain.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cirrus.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cirrus.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-dinersclub.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-dinersclub.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-discover.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-discover.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-echeck.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-echeck.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-google.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-google.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-jcb.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-jcb.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-laser.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-laser.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-maestro.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-maestro.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-mastercard.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-mastercard.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-moneybookers.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-moneybookers.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-paypal.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-paypal.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-solo.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-solo.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-switch.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-switch.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-debit.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-debit.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-electron.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-electron.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa.png +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa.svg +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/license.txt +0 -0
- {vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/sample-check.png +0 -0
- assets/js/admin/wc-square-admin-products.min.js +1 -1
- assets/js/admin/wc-square-admin-settings.min.js +1 -1
- assets/js/admin/wc-square-payment-gateway-admin-order.min.js +1 -0
- assets/js/admin/wc-square-payment-gateway-token-editor.min.js +1 -0
- assets/js/frontend/wc-square-digital-wallet.min.js +1 -1
- assets/js/frontend/wc-square-payment-gateway-apple-pay.min.js +1 -0
- assets/js/frontend/wc-square-payment-gateway-my-payment-methods.min.js +1 -0
- assets/js/frontend/wc-square-payment-gateway-payment-form.min.js +1 -0
- assets/js/frontend/wc-square.min.js +1 -1
- build/index.asset.php +1 -1
- build/index.js +1 -1
- changelog.txt +277 -0
- composer.json +0 -26
- i18n/languages/woocommerce-square.pot +1872 -1936
- includes/AJAX.php +3 -40
- includes/API.php +76 -91
- includes/API/Request.php +3 -6
- includes/API/Requests/Catalog.php +47 -57
- includes/API/Requests/Customers.php +3 -5
- includes/API/Requests/Inventory.php +33 -23
- includes/API/Requests/Locations.php +2 -7
- includes/API/Response.php +18 -11
- includes/API/Responses/Catalog.php +1 -2
- includes/API/Responses/Connection_Refresh_Response.php +2 -6
- includes/API/Responses/Inventory.php +2 -3
- includes/API/Responses/Locations.php +2 -4
- includes/Admin.php +0 -1
- includes/Admin/Privacy.php +0 -2
- includes/Admin/Settings_Page.php +0 -1
- includes/Admin/Sync_Page.php +0 -1
- includes/Emails/Access_Token_Email.php +0 -2
- includes/Emails/Base_Email.php +2 -2
- includes/Emails/Sync_Completed.php +7 -19
- includes/Framework/Addresses/Address.php +263 -0
- includes/Framework/Addresses/Customer_Address.php +128 -0
- includes/Framework/Admin_Message_Handler.php +392 -0
- includes/Framework/Admin_Notice_Handler.php +380 -0
- includes/Framework/Api/API_JSON_Request.php +105 -0
- includes/Framework/Api/API_JSON_Response.php +67 -0
- includes/Framework/Api/API_Request.php +62 -0
- includes/Framework/Api/API_Response.php +25 -0
- includes/Framework/Api/Base.php +659 -0
- includes/Framework/Compatibility/Data_Compatibility.php +114 -0
- includes/Framework/Compatibility/Order_Compatibility.php +243 -0
- includes/Framework/Lifecycle.php +550 -0
- includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php +434 -0
- includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php +668 -0
- includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_User_Handler.php +381 -0
- includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php +79 -0
- includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php +45 -0
- includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor-token.php +71 -0
- includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor.php +65 -0
- includes/Framework/PaymentGateway/Admin/views/html-user-profile-field-customer-id.php +7 -0
- includes/Framework/PaymentGateway/Admin/views/html-user-profile-section.php +25 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_API_Response.php +91 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api.php +220 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Authorization_Response.php +55 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Create_Payment_Token_Response.php +22 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Customer_Response.php +19 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Get_Tokenized_Payment_Methods_Response.php +21 -0
- includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php +88 -0
- includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api.php +176 -0
- includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api_Request.php +96 -0
- includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api_Response.php +93 -0
- includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Payment_Response.php +189 -0
- includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php +1029 -0
- includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php +392 -0
- includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Ajax.php +240 -0
- includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php +340 -0
- includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php +178 -0
- includes/Framework/PaymentGateway/Handlers/Capture.php +400 -0
- includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration.php +43 -0
- includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php +351 -0
- includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php +673 -0
- includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Token.php +366 -0
- includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php +859 -0
- includes/Framework/PaymentGateway/Payment_Gateway.php +3813 -0
- includes/Framework/PaymentGateway/Payment_Gateway_Direct.php +1007 -0
- includes/Framework/PaymentGateway/Payment_Gateway_Helper.php +238 -0
- includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php +931 -0
assets/css/admin/wc-square-payment-gateway-admin-order.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
#woocommerce-order-items .sv-wc-payment-gateway-partial-capture .capture-actions{margin-top:5px;padding-top:12px;border-top:1px solid #dfdfdf}#woocommerce-order-items .sv-wc-payment-gateway-partial-capture .capture-actions .button{float:right;margin-left:4px}#woocommerce-order-items .sv-wc-payment-gateway-partial-capture .capture-actions .cancel-action{float:left;margin-left:0}
|
assets/css/admin/wc-square-payment-gateway-token-editor.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
table.sv_wc_payment_gateway_token_editor{width:auto}table.sv_wc_payment_gateway_token_editor th{padding:9px 7px!important;vertical-align:middle}table.sv_wc_payment_gateway_token_editor td{vertical-align:middle;padding:10px 7px;line-height:2em}table.sv_wc_payment_gateway_token_editor tr:nth-child(odd) td{background:#f9f9f9}table.sv_wc_payment_gateway_token_editor tr.token input.error{border-color:#a00}table.sv_wc_payment_gateway_token_editor .token-default{text-align:center}table.sv_wc_payment_gateway_token_editor .token-actions{text-align:right}table.sv_wc_payment_gateway_token_editor .actions{font-weight:400;text-align:right}table.sv_wc_payment_gateway_token_editor .actions .error{color:#a00;padding-right:10px;font-weight:700}
|
assets/css/frontend/wc-square-digital-wallet.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#wc-square-digital-wallet{display:none;clear:both;padding-top:1.5em;width:100%;max-width:510px;margin:0 auto}#wc-square-wallet-divider{margin-top:1em;text-align:center}.wc-square-wallet-buttons{width:99%;height:44px;margin:0 0 1em 0;cursor:pointer;display:none}.wc-square-wallet-button-black{background-color:#000}.wc-square-wallet-button-white{background-color:#fff}.google-pay-button{padding:11px 10px;background-origin:content-box;background-position:center;background-repeat:no-repeat;background-size:contain;border:0;border-radius:4px;box-shadow:0 1px 1px 0 rgba(60,64,67,.3),0 1px 3px 1px rgba(60,64,67,.15);outline:0;cursor:pointer}.google-pay-button.wc-square-wallet-button-black{background-image:url(data:image/svg+xml,%3Csvg%20width%3D%22103%22%20height%3D%2217%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M.148%202.976h3.766c.532%200%201.024.117%201.477.35.453.233.814.555%201.085.966.27.41.406.863.406%201.358%200%20.495-.124.924-.371%201.288s-.572.64-.973.826v.084c.504.177.912.471%201.225.882.313.41.469.891.469%201.442a2.6%202.6%200%200%201-.427%201.47c-.285.43-.667.763-1.148%201.001A3.5%203.5%200%200%201%204.082%2013H.148V2.976zm3.696%204.2c.448%200%20.81-.14%201.085-.42.275-.28.413-.602.413-.966s-.133-.684-.399-.959c-.266-.275-.614-.413-1.043-.413H1.716v2.758h2.128zm.238%204.368c.476%200%20.856-.15%201.141-.448.285-.299.427-.644.427-1.036%200-.401-.147-.749-.441-1.043-.294-.294-.688-.441-1.183-.441h-2.31v2.968h2.366zm5.379.903c-.453-.518-.679-1.239-.679-2.163V5.86h1.54v4.214c0%20.579.138%201.013.413%201.302.275.29.637.434%201.085.434.364%200%20.686-.096.966-.287.28-.191.495-.446.644-.763a2.37%202.37%200%200%200%20.224-1.022V5.86h1.54V13h-1.456v-.924h-.084c-.196.336-.5.611-.91.826-.41.215-.845.322-1.302.322-.868%200-1.528-.259-1.981-.777zm9.859.161L16.352%205.86h1.722l2.016%204.858h.056l1.96-4.858H23.8l-4.41%2010.164h-1.624l1.554-3.416zm8.266-6.748h1.666l1.442%205.11h.056l1.61-5.11h1.582l1.596%205.11h.056l1.442-5.11h1.638L36.392%2013h-1.624L33.13%207.876h-.042L31.464%2013h-1.596l-2.282-7.14zm12.379-1.337a1%201%200%200%201-.301-.735%201%201%200%200%201%20.301-.735%201%201%200%200%201%20.735-.301%201%201%200%200%201%20.735.301%201%201%200%200%201%20.301.735%201%201%200%200%201-.301.735%201%201%200%200%201-.735.301%201%201%200%200%201-.735-.301zM39.93%205.86h1.54V13h-1.54V5.86zm5.568%207.098a1.967%201.967%200%200%201-.686-.406c-.401-.401-.602-.947-.602-1.638V7.218h-1.246V5.86h1.246V3.844h1.54V5.86h1.736v1.358H45.75v3.36c0%20.383.075.653.224.812.14.187.383.28.728.28.159%200%20.299-.021.42-.063.121-.042.252-.11.392-.203v1.498c-.308.14-.681.21-1.12.21-.317%200-.616-.051-.896-.154zm3.678-9.982h1.54v2.73l-.07%201.092h.07c.205-.336.511-.614.917-.833.406-.22.842-.329%201.309-.329.868%200%201.53.254%201.988.763.457.509.686%201.202.686%202.079V13h-1.54V8.688c0-.541-.142-.947-.427-1.218-.285-.27-.656-.406-1.113-.406-.345%200-.656.098-.931.294a2.042%202.042%200%200%200-.651.777%202.297%202.297%200%200%200-.238%201.029V13h-1.54V2.976zm32.35-.341v4.083h2.518c.6%200%201.096-.202%201.488-.605.403-.402.605-.882.605-1.437%200-.544-.202-1.018-.605-1.422-.392-.413-.888-.62-1.488-.62h-2.518zm0%205.52v4.736h-1.504V1.198h3.99c1.013%200%201.873.337%202.582%201.012.72.675%201.08%201.497%201.08%202.466%200%20.991-.36%201.819-1.08%202.482-.697.665-1.559.996-2.583.996h-2.485v.001zm7.668%202.287c0%20.392.166.718.499.98.332.26.722.391%201.168.391.633%200%201.196-.234%201.692-.701.497-.469.744-1.019.744-1.65-.469-.37-1.123-.555-1.962-.555-.61%200-1.12.148-1.528.442-.409.294-.613.657-.613%201.093m1.946-5.815c1.112%200%201.989.297%202.633.89.642.594.964%201.408.964%202.442v4.932h-1.439v-1.11h-.065c-.622.914-1.45%201.372-2.486%201.372-.882%200-1.621-.262-2.215-.784-.594-.523-.891-1.176-.891-1.96%200-.828.313-1.486.94-1.976s1.463-.735%202.51-.735c.892%200%201.629.163%202.206.49v-.344c0-.522-.207-.966-.621-1.33a2.132%202.132%200%200%200-1.455-.547c-.84%200-1.504.353-1.995%201.062l-1.324-.834c.73-1.045%201.81-1.568%203.238-1.568m11.853.262l-5.02%2011.53H96.42l1.864-4.034-3.302-7.496h1.635l2.387%205.749h.032l2.322-5.75z%22%20fill%3D%22%23FFF%22%2F%3E%3Cpath%20d%3D%22M75.448%207.134c0-.473-.04-.93-.116-1.366h-6.344v2.588h3.634a3.11%203.11%200%200%201-1.344%202.042v1.68h2.169c1.27-1.17%202.001-2.9%202.001-4.944%22%20fill%3D%22%234285F4%22%2F%3E%3Cpath%20d%3D%22M68.988%2013.7c1.816%200%203.344-.595%204.459-1.621l-2.169-1.681c-.603.406-1.38.643-2.29.643-1.754%200-3.244-1.182-3.776-2.774h-2.234v1.731a6.728%206.728%200%200%200%206.01%203.703%22%20fill%3D%22%2334A853%22%2F%3E%3Cpath%20d%3D%22M65.212%208.267a4.034%204.034%200%200%201%200-2.572V3.964h-2.234a6.678%206.678%200%200%200-.717%203.017c0%201.085.26%202.11.717%203.017l2.234-1.731z%22%20fill%3D%22%23FABB05%22%2F%3E%3Cpath%20d%3D%22M68.988%202.921c.992%200%201.88.34%202.58%201.008v.001l1.92-1.918c-1.165-1.084-2.685-1.75-4.5-1.75a6.728%206.728%200%200%200-6.01%203.702l2.234%201.731c.532-1.592%202.022-2.774%203.776-2.774%22%20fill%3D%22%23E94235%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E)}.google-pay-button.wc-square-wallet-button-white{background-image:url(data:image/svg+xml,%3Csvg%20width%3D%22103%22%20height%3D%2217%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M.148%202.976h3.766c.532%200%201.024.117%201.477.35.453.233.814.555%201.085.966.27.41.406.863.406%201.358%200%20.495-.124.924-.371%201.288s-.572.64-.973.826v.084c.504.177.912.471%201.225.882.313.41.469.891.469%201.442a2.6%202.6%200%200%201-.427%201.47c-.285.43-.667.763-1.148%201.001A3.5%203.5%200%200%201%204.082%2013H.148V2.976zm3.696%204.2c.448%200%20.81-.14%201.085-.42.275-.28.413-.602.413-.966s-.133-.684-.399-.959c-.266-.275-.614-.413-1.043-.413H1.716v2.758h2.128zm.238%204.368c.476%200%20.856-.15%201.141-.448.285-.299.427-.644.427-1.036%200-.401-.147-.749-.441-1.043-.294-.294-.688-.441-1.183-.441h-2.31v2.968h2.366zm5.379.903c-.453-.518-.679-1.239-.679-2.163V5.86h1.54v4.214c0%20.579.138%201.013.413%201.302.275.29.637.434%201.085.434.364%200%20.686-.096.966-.287.28-.191.495-.446.644-.763a2.37%202.37%200%200%200%20.224-1.022V5.86h1.54V13h-1.456v-.924h-.084c-.196.336-.5.611-.91.826-.41.215-.845.322-1.302.322-.868%200-1.528-.259-1.981-.777zm9.859.161L16.352%205.86h1.722l2.016%204.858h.056l1.96-4.858H23.8l-4.41%2010.164h-1.624l1.554-3.416zm8.266-6.748h1.666l1.442%205.11h.056l1.61-5.11h1.582l1.596%205.11h.056l1.442-5.11h1.638L36.392%2013h-1.624L33.13%207.876h-.042L31.464%2013h-1.596l-2.282-7.14zm12.379-1.337a1%201%200%200%201-.301-.735%201%201%200%200%201%20.301-.735%201%201%200%200%201%20.735-.301%201%201%200%200%201%20.735.301%201%201%200%200%201%20.301.735%201%201%200%200%201-.301.735%201%201%200%200%201-.735.301%201%201%200%200%201-.735-.301zM39.93%205.86h1.54V13h-1.54V5.86zm5.568%207.098a1.967%201.967%200%200%201-.686-.406c-.401-.401-.602-.947-.602-1.638V7.218h-1.246V5.86h1.246V3.844h1.54V5.86h1.736v1.358H45.75v3.36c0%20.383.075.653.224.812.14.187.383.28.728.28.159%200%20.299-.021.42-.063.121-.042.252-.11.392-.203v1.498c-.308.14-.681.21-1.12.21-.317%200-.616-.051-.896-.154zm3.678-9.982h1.54v2.73l-.07%201.092h.07c.205-.336.511-.614.917-.833.406-.22.842-.329%201.309-.329.868%200%201.53.254%201.988.763.457.509.686%201.202.686%202.079V13h-1.54V8.688c0-.541-.142-.947-.427-1.218-.285-.27-.656-.406-1.113-.406-.345%200-.656.098-.931.294a2.042%202.042%200%200%200-.651.777%202.297%202.297%200%200%200-.238%201.029V13h-1.54V2.976zm32.35-.341v4.083h2.518c.6%200%201.096-.202%201.488-.605.403-.402.605-.882.605-1.437%200-.544-.202-1.018-.605-1.422-.392-.413-.888-.62-1.488-.62h-2.518zm0%205.52v4.736h-1.504V1.198h3.99c1.013%200%201.873.337%202.582%201.012.72.675%201.08%201.497%201.08%202.466%200%20.991-.36%201.819-1.08%202.482-.697.665-1.559.996-2.583.996h-2.485v.001zm7.668%202.287c0%20.392.166.718.499.98.332.26.722.391%201.168.391.633%200%201.196-.234%201.692-.701.497-.469.744-1.019.744-1.65-.469-.37-1.123-.555-1.962-.555-.61%200-1.12.148-1.528.442-.409.294-.613.657-.613%201.093m1.946-5.815c1.112%200%201.989.297%202.633.89.642.594.964%201.408.964%202.442v4.932h-1.439v-1.11h-.065c-.622.914-1.45%201.372-2.486%201.372-.882%200-1.621-.262-2.215-.784-.594-.523-.891-1.176-.891-1.96%200-.828.313-1.486.94-1.976s1.463-.735%202.51-.735c.892%200%201.629.163%202.206.49v-.344c0-.522-.207-.966-.621-1.33a2.132%202.132%200%200%200-1.455-.547c-.84%200-1.504.353-1.995%201.062l-1.324-.834c.73-1.045%201.81-1.568%203.238-1.568m11.853.262l-5.02%2011.53H96.42l1.864-4.034-3.302-7.496h1.635l2.387%205.749h.032l2.322-5.75z%22%20fill%3D%22%23000%22%2F%3E%3Cpath%20d%3D%22M75.448%207.134c0-.473-.04-.93-.116-1.366h-6.344v2.588h3.634a3.11%203.11%200%200%201-1.344%202.042v1.68h2.169c1.27-1.17%202.001-2.9%202.001-4.944%22%20fill%3D%22%234285F4%22%2F%3E%3Cpath%20d%3D%22M68.988%2013.7c1.816%200%203.344-.595%204.459-1.621l-2.169-1.681c-.603.406-1.38.643-2.29.643-1.754%200-3.244-1.182-3.776-2.774h-2.234v1.731a6.728%206.728%200%200%200%206.01%203.703%22%20fill%3D%22%2334A853%22%2F%3E%3Cpath%20d%3D%22M65.212%208.267a4.034%204.034%200%200%201%200-2.572V3.964h-2.234a6.678%206.678%200%200%200-.717%203.017c0%201.085.26%202.11.717%203.017l2.234-1.731z%22%20fill%3D%22%23FABB05%22%2F%3E%3Cpath%20d%3D%22M68.988%202.921c.992%200%201.88.34%202.58%201.008v.001l1.92-1.918c-1.165-1.084-2.685-1.75-4.5-1.75a6.728%206.728%200%200%200-6.01%203.702l2.234%201.731c.532-1.592%202.022-2.774%203.776-2.774%22%20fill%3D%22%23E94235%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E)}@supports (-webkit-appearance:-apple-pay-button){.apple-pay-button{-webkit-appearance:-apple-pay-button;cursor:pointer}.apple-pay-button>*{display:none}}@supports not (-webkit-appearance:-apple-pay-button){.apple-pay-button{background-size:100% 60%;background-repeat:no-repeat;background-position:50% 50%;border-radius:5px;padding:0;box-sizing:border-box;min-width:200px;min-height:32px;max-height:64px;cursor:pointer}.apple-pay-button.wc-square-wallet-button-with-text{--apple-pay-scale:1;justify-content:center;font-size:12px;background:0 0}.apple-pay-button.wc-square-wallet-button-with-text .text{font-family:-apple-system;font-size:calc(1em * var(--apple-pay-scale));font-weight:300;align-self:center;margin-right:calc(2px * var(--apple-pay-scale))}.apple-pay-button.wc-square-wallet-button-with-text .logo{width:calc(35px * var(--scale));height:100%;background-size:100% 60%;background-repeat:no-repeat;background-position:0 50%;margin-left:calc(2px * var(--apple-pay-scale));border:none}.apple-pay-button.wc-square-wallet-button-black{background-color:#000;color:#fff}.apple-pay-button.wc-square-wallet-button-black .logo{background-image:-webkit-named-image(apple-pay-logo-white);background-color:#000}.apple-pay-button.wc-square-wallet-button-white{background-color:#fff;color:#000}.apple-pay-button.wc-square-wallet-button-white .logo{background-image:-webkit-named-image(apple-pay-logo-black);background-color:#fff}.apple-pay-button.wc-square-wallet-button-white-outline{background-color:#fff;color:#000;border:.5px solid #000}.apple-pay-button.wc-square-wallet-button-white-outline .logo{background-image:-webkit-named-image(apple-pay-logo-black);background-color:#fff}}
|
1 |
+
#wc-square-digital-wallet{display:none;clear:both;padding-top:1.5em;width:100%;max-width:510px;margin:0 auto}#wc-square-wallet-divider{margin-top:1em;text-align:center}.wc-square-wallet-buttons{height:40px;margin:0 0 1em 0;cursor:pointer;display:none}.wc-square-wallet-button-black{background-color:#000}.wc-square-wallet-button-white{background-color:#fff}.google-pay-button{padding:11px 10px;background-origin:content-box;background-position:center;background-repeat:no-repeat;background-size:contain;border:0;border-radius:4px;box-shadow:0 1px 1px 0 rgba(60,64,67,.3),0 1px 3px 1px rgba(60,64,67,.15);outline:0;cursor:pointer}.google-pay-button.wc-square-wallet-button-black{background-image:url(data:image/svg+xml,%3Csvg%20width%3D%22103%22%20height%3D%2217%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M.148%202.976h3.766c.532%200%201.024.117%201.477.35.453.233.814.555%201.085.966.27.41.406.863.406%201.358%200%20.495-.124.924-.371%201.288s-.572.64-.973.826v.084c.504.177.912.471%201.225.882.313.41.469.891.469%201.442a2.6%202.6%200%200%201-.427%201.47c-.285.43-.667.763-1.148%201.001A3.5%203.5%200%200%201%204.082%2013H.148V2.976zm3.696%204.2c.448%200%20.81-.14%201.085-.42.275-.28.413-.602.413-.966s-.133-.684-.399-.959c-.266-.275-.614-.413-1.043-.413H1.716v2.758h2.128zm.238%204.368c.476%200%20.856-.15%201.141-.448.285-.299.427-.644.427-1.036%200-.401-.147-.749-.441-1.043-.294-.294-.688-.441-1.183-.441h-2.31v2.968h2.366zm5.379.903c-.453-.518-.679-1.239-.679-2.163V5.86h1.54v4.214c0%20.579.138%201.013.413%201.302.275.29.637.434%201.085.434.364%200%20.686-.096.966-.287.28-.191.495-.446.644-.763a2.37%202.37%200%200%200%20.224-1.022V5.86h1.54V13h-1.456v-.924h-.084c-.196.336-.5.611-.91.826-.41.215-.845.322-1.302.322-.868%200-1.528-.259-1.981-.777zm9.859.161L16.352%205.86h1.722l2.016%204.858h.056l1.96-4.858H23.8l-4.41%2010.164h-1.624l1.554-3.416zm8.266-6.748h1.666l1.442%205.11h.056l1.61-5.11h1.582l1.596%205.11h.056l1.442-5.11h1.638L36.392%2013h-1.624L33.13%207.876h-.042L31.464%2013h-1.596l-2.282-7.14zm12.379-1.337a1%201%200%200%201-.301-.735%201%201%200%200%201%20.301-.735%201%201%200%200%201%20.735-.301%201%201%200%200%201%20.735.301%201%201%200%200%201%20.301.735%201%201%200%200%201-.301.735%201%201%200%200%201-.735.301%201%201%200%200%201-.735-.301zM39.93%205.86h1.54V13h-1.54V5.86zm5.568%207.098a1.967%201.967%200%200%201-.686-.406c-.401-.401-.602-.947-.602-1.638V7.218h-1.246V5.86h1.246V3.844h1.54V5.86h1.736v1.358H45.75v3.36c0%20.383.075.653.224.812.14.187.383.28.728.28.159%200%20.299-.021.42-.063.121-.042.252-.11.392-.203v1.498c-.308.14-.681.21-1.12.21-.317%200-.616-.051-.896-.154zm3.678-9.982h1.54v2.73l-.07%201.092h.07c.205-.336.511-.614.917-.833.406-.22.842-.329%201.309-.329.868%200%201.53.254%201.988.763.457.509.686%201.202.686%202.079V13h-1.54V8.688c0-.541-.142-.947-.427-1.218-.285-.27-.656-.406-1.113-.406-.345%200-.656.098-.931.294a2.042%202.042%200%200%200-.651.777%202.297%202.297%200%200%200-.238%201.029V13h-1.54V2.976zm32.35-.341v4.083h2.518c.6%200%201.096-.202%201.488-.605.403-.402.605-.882.605-1.437%200-.544-.202-1.018-.605-1.422-.392-.413-.888-.62-1.488-.62h-2.518zm0%205.52v4.736h-1.504V1.198h3.99c1.013%200%201.873.337%202.582%201.012.72.675%201.08%201.497%201.08%202.466%200%20.991-.36%201.819-1.08%202.482-.697.665-1.559.996-2.583.996h-2.485v.001zm7.668%202.287c0%20.392.166.718.499.98.332.26.722.391%201.168.391.633%200%201.196-.234%201.692-.701.497-.469.744-1.019.744-1.65-.469-.37-1.123-.555-1.962-.555-.61%200-1.12.148-1.528.442-.409.294-.613.657-.613%201.093m1.946-5.815c1.112%200%201.989.297%202.633.89.642.594.964%201.408.964%202.442v4.932h-1.439v-1.11h-.065c-.622.914-1.45%201.372-2.486%201.372-.882%200-1.621-.262-2.215-.784-.594-.523-.891-1.176-.891-1.96%200-.828.313-1.486.94-1.976s1.463-.735%202.51-.735c.892%200%201.629.163%202.206.49v-.344c0-.522-.207-.966-.621-1.33a2.132%202.132%200%200%200-1.455-.547c-.84%200-1.504.353-1.995%201.062l-1.324-.834c.73-1.045%201.81-1.568%203.238-1.568m11.853.262l-5.02%2011.53H96.42l1.864-4.034-3.302-7.496h1.635l2.387%205.749h.032l2.322-5.75z%22%20fill%3D%22%23FFF%22%2F%3E%3Cpath%20d%3D%22M75.448%207.134c0-.473-.04-.93-.116-1.366h-6.344v2.588h3.634a3.11%203.11%200%200%201-1.344%202.042v1.68h2.169c1.27-1.17%202.001-2.9%202.001-4.944%22%20fill%3D%22%234285F4%22%2F%3E%3Cpath%20d%3D%22M68.988%2013.7c1.816%200%203.344-.595%204.459-1.621l-2.169-1.681c-.603.406-1.38.643-2.29.643-1.754%200-3.244-1.182-3.776-2.774h-2.234v1.731a6.728%206.728%200%200%200%206.01%203.703%22%20fill%3D%22%2334A853%22%2F%3E%3Cpath%20d%3D%22M65.212%208.267a4.034%204.034%200%200%201%200-2.572V3.964h-2.234a6.678%206.678%200%200%200-.717%203.017c0%201.085.26%202.11.717%203.017l2.234-1.731z%22%20fill%3D%22%23FABB05%22%2F%3E%3Cpath%20d%3D%22M68.988%202.921c.992%200%201.88.34%202.58%201.008v.001l1.92-1.918c-1.165-1.084-2.685-1.75-4.5-1.75a6.728%206.728%200%200%200-6.01%203.702l2.234%201.731c.532-1.592%202.022-2.774%203.776-2.774%22%20fill%3D%22%23E94235%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E)}.google-pay-button.wc-square-wallet-button-white{background-image:url(data:image/svg+xml,%3Csvg%20width%3D%22103%22%20height%3D%2217%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M.148%202.976h3.766c.532%200%201.024.117%201.477.35.453.233.814.555%201.085.966.27.41.406.863.406%201.358%200%20.495-.124.924-.371%201.288s-.572.64-.973.826v.084c.504.177.912.471%201.225.882.313.41.469.891.469%201.442a2.6%202.6%200%200%201-.427%201.47c-.285.43-.667.763-1.148%201.001A3.5%203.5%200%200%201%204.082%2013H.148V2.976zm3.696%204.2c.448%200%20.81-.14%201.085-.42.275-.28.413-.602.413-.966s-.133-.684-.399-.959c-.266-.275-.614-.413-1.043-.413H1.716v2.758h2.128zm.238%204.368c.476%200%20.856-.15%201.141-.448.285-.299.427-.644.427-1.036%200-.401-.147-.749-.441-1.043-.294-.294-.688-.441-1.183-.441h-2.31v2.968h2.366zm5.379.903c-.453-.518-.679-1.239-.679-2.163V5.86h1.54v4.214c0%20.579.138%201.013.413%201.302.275.29.637.434%201.085.434.364%200%20.686-.096.966-.287.28-.191.495-.446.644-.763a2.37%202.37%200%200%200%20.224-1.022V5.86h1.54V13h-1.456v-.924h-.084c-.196.336-.5.611-.91.826-.41.215-.845.322-1.302.322-.868%200-1.528-.259-1.981-.777zm9.859.161L16.352%205.86h1.722l2.016%204.858h.056l1.96-4.858H23.8l-4.41%2010.164h-1.624l1.554-3.416zm8.266-6.748h1.666l1.442%205.11h.056l1.61-5.11h1.582l1.596%205.11h.056l1.442-5.11h1.638L36.392%2013h-1.624L33.13%207.876h-.042L31.464%2013h-1.596l-2.282-7.14zm12.379-1.337a1%201%200%200%201-.301-.735%201%201%200%200%201%20.301-.735%201%201%200%200%201%20.735-.301%201%201%200%200%201%20.735.301%201%201%200%200%201%20.301.735%201%201%200%200%201-.301.735%201%201%200%200%201-.735.301%201%201%200%200%201-.735-.301zM39.93%205.86h1.54V13h-1.54V5.86zm5.568%207.098a1.967%201.967%200%200%201-.686-.406c-.401-.401-.602-.947-.602-1.638V7.218h-1.246V5.86h1.246V3.844h1.54V5.86h1.736v1.358H45.75v3.36c0%20.383.075.653.224.812.14.187.383.28.728.28.159%200%20.299-.021.42-.063.121-.042.252-.11.392-.203v1.498c-.308.14-.681.21-1.12.21-.317%200-.616-.051-.896-.154zm3.678-9.982h1.54v2.73l-.07%201.092h.07c.205-.336.511-.614.917-.833.406-.22.842-.329%201.309-.329.868%200%201.53.254%201.988.763.457.509.686%201.202.686%202.079V13h-1.54V8.688c0-.541-.142-.947-.427-1.218-.285-.27-.656-.406-1.113-.406-.345%200-.656.098-.931.294a2.042%202.042%200%200%200-.651.777%202.297%202.297%200%200%200-.238%201.029V13h-1.54V2.976zm32.35-.341v4.083h2.518c.6%200%201.096-.202%201.488-.605.403-.402.605-.882.605-1.437%200-.544-.202-1.018-.605-1.422-.392-.413-.888-.62-1.488-.62h-2.518zm0%205.52v4.736h-1.504V1.198h3.99c1.013%200%201.873.337%202.582%201.012.72.675%201.08%201.497%201.08%202.466%200%20.991-.36%201.819-1.08%202.482-.697.665-1.559.996-2.583.996h-2.485v.001zm7.668%202.287c0%20.392.166.718.499.98.332.26.722.391%201.168.391.633%200%201.196-.234%201.692-.701.497-.469.744-1.019.744-1.65-.469-.37-1.123-.555-1.962-.555-.61%200-1.12.148-1.528.442-.409.294-.613.657-.613%201.093m1.946-5.815c1.112%200%201.989.297%202.633.89.642.594.964%201.408.964%202.442v4.932h-1.439v-1.11h-.065c-.622.914-1.45%201.372-2.486%201.372-.882%200-1.621-.262-2.215-.784-.594-.523-.891-1.176-.891-1.96%200-.828.313-1.486.94-1.976s1.463-.735%202.51-.735c.892%200%201.629.163%202.206.49v-.344c0-.522-.207-.966-.621-1.33a2.132%202.132%200%200%200-1.455-.547c-.84%200-1.504.353-1.995%201.062l-1.324-.834c.73-1.045%201.81-1.568%203.238-1.568m11.853.262l-5.02%2011.53H96.42l1.864-4.034-3.302-7.496h1.635l2.387%205.749h.032l2.322-5.75z%22%20fill%3D%22%23000%22%2F%3E%3Cpath%20d%3D%22M75.448%207.134c0-.473-.04-.93-.116-1.366h-6.344v2.588h3.634a3.11%203.11%200%200%201-1.344%202.042v1.68h2.169c1.27-1.17%202.001-2.9%202.001-4.944%22%20fill%3D%22%234285F4%22%2F%3E%3Cpath%20d%3D%22M68.988%2013.7c1.816%200%203.344-.595%204.459-1.621l-2.169-1.681c-.603.406-1.38.643-2.29.643-1.754%200-3.244-1.182-3.776-2.774h-2.234v1.731a6.728%206.728%200%200%200%206.01%203.703%22%20fill%3D%22%2334A853%22%2F%3E%3Cpath%20d%3D%22M65.212%208.267a4.034%204.034%200%200%201%200-2.572V3.964h-2.234a6.678%206.678%200%200%200-.717%203.017c0%201.085.26%202.11.717%203.017l2.234-1.731z%22%20fill%3D%22%23FABB05%22%2F%3E%3Cpath%20d%3D%22M68.988%202.921c.992%200%201.88.34%202.58%201.008v.001l1.92-1.918c-1.165-1.084-2.685-1.75-4.5-1.75a6.728%206.728%200%200%200-6.01%203.702l2.234%201.731c.532-1.592%202.022-2.774%203.776-2.774%22%20fill%3D%22%23E94235%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E)}@supports (-webkit-appearance:-apple-pay-button){.apple-pay-button{-webkit-appearance:-apple-pay-button;cursor:pointer}.apple-pay-button>*{display:none}}@supports not (-webkit-appearance:-apple-pay-button){.apple-pay-button{background-size:100% 60%;background-repeat:no-repeat;background-position:50% 50%;border-radius:5px;padding:0;box-sizing:border-box;min-width:200px;min-height:32px;max-height:64px;cursor:pointer}.apple-pay-button.wc-square-wallet-button-with-text{--apple-pay-scale:1;justify-content:center;font-size:12px;background:0 0}.apple-pay-button.wc-square-wallet-button-with-text .text{font-family:-apple-system;font-size:calc(1em * var(--apple-pay-scale));font-weight:300;align-self:center;margin-right:calc(2px * var(--apple-pay-scale))}.apple-pay-button.wc-square-wallet-button-with-text .logo{width:calc(35px * var(--scale));height:100%;background-size:100% 60%;background-repeat:no-repeat;background-position:0 50%;margin-left:calc(2px * var(--apple-pay-scale));border:none}.apple-pay-button.wc-square-wallet-button-black{background-color:#000;color:#fff}.apple-pay-button.wc-square-wallet-button-black .logo{background-image:-webkit-named-image(apple-pay-logo-white);background-color:#000}.apple-pay-button.wc-square-wallet-button-white{background-color:#fff;color:#000}.apple-pay-button.wc-square-wallet-button-white .logo{background-image:-webkit-named-image(apple-pay-logo-black);background-color:#fff}.apple-pay-button.wc-square-wallet-button-white-outline{background-color:#fff;color:#000;border:.5px solid #000}.apple-pay-button.wc-square-wallet-button-white-outline .logo{background-image:-webkit-named-image(apple-pay-logo-black);background-color:#fff}}
|
assets/css/frontend/wc-square-payment-gateway-my-payment-methods.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
table.sv-wc-payment-gateway-my-payment-methods-table{font-size:.85em}table.sv-wc-payment-gateway-my-payment-methods-table td,table.sv-wc-payment-gateway-my-payment-methods-table th{vertical-align:middle}table.sv-wc-payment-gateway-my-payment-methods-table .button{white-space:nowrap}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-actions span,table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-default span,table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-details span{display:none}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-default,table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-expiry{text-align:center}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-payment-method-header-actions{text-align:right}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-title input{width:100%}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-details{white-space:nowrap}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-details img{width:40px;height:25px;margin-right:.5em;vertical-align:middle;display:inline!important}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-expiry{text-align:center}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-default{text-align:center}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-default mark{display:inline-block;color:#fff;background-color:#3d9cd2;font-size:.75em;text-transform:uppercase;padding:2px 4px;border-radius:2px}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions{text-align:right}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions .button{margin:.125em 0 .125em .25em}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions .button.disabled.tip:hover{cursor:help}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .cancel-edit-payment-method{margin-right:.5em}table.sv-wc-payment-gateway-my-payment-methods-table.editing .sv-wc-payment-gateway-payment-method-header-default span{display:inline}table.sv-wc-payment-gateway-my-payment-methods-table.editing .sv-wc-payment-gateway-my-payment-methods-method:not(.editing),table.sv-wc-payment-gateway-my-payment-methods-table.editing .sv-wc-payment-gateway-my-payment-methods-type-divider{opacity:.5}table.sv-wc-payment-gateway-my-payment-methods-table.editing .sv-wc-payment-gateway-my-payment-methods-method:hover{opacity:1}table.sv-wc-payment-gateway-my-payment-methods-table tr.sv-wc-payment-gateway-my-payment-methods-type-divider td{font-weight:700}table.sv-wc-payment-gateway-my-payment-methods-table .error td{color:#fff;text-align:center;background-color:#e26838;border-radius:0 0 3px 3px;padding:5px}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:99999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#464646}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#464646}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#464646}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#464646}#tiptip_content,.chart-tooltip{font-size:11px;color:#fff;padding:.5em .5em;background:#464646;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:1px 1px 3px rgba(0,0,0,.1);-moz-box-shadow:1px 1px 3px rgba(0,0,0,.1);box-shadow:1px 1px 3px rgba(0,0,0,.1);text-align:center;max-width:150px}#tiptip_content code,.chart-tooltip code{background:#888;padding:1px}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}@media screen and (max-width:768px){table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-default,table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-expiry{text-align:right}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions{text-align:right}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions:before{display:none}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-method .sv-wc-payment-gateway-payment-method-actions .button{float:none;margin:.125em .25em .125em 0}table.sv-wc-payment-gateway-my-payment-methods-table .sv-wc-payment-gateway-my-payment-methods-type-divider td:before{display:none}}
|
assets/css/frontend/wc-square-payment-gateway-payment-form.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
#add_payment_method .sv-wc-payment-gateway-payment-form-manage-payment-methods,.woocommerce-checkout #payment div.payment_box .sv-wc-payment-gateway-payment-form-manage-payment-methods{display:block;margin:1em 0;text-align:center}#add_payment_method .sv-wc-payment-gateway-payment-form-saved-payment-method,.woocommerce-checkout #payment div.payment_box .sv-wc-payment-gateway-payment-form-saved-payment-method{display:inline-block;margin-bottom:.5em}#add_payment_method .sv-wc-payment-gateway-payment-form-saved-payment-method .nickname,.woocommerce-checkout #payment div.payment_box .sv-wc-payment-gateway-payment-form-saved-payment-method .nickname{margin-right:.5em}#add_payment_method .sv-wc-payment-gateway-payment-form-saved-payment-method img,.woocommerce-checkout #payment div.payment_box .sv-wc-payment-gateway-payment-form-saved-payment-method img{float:none;width:30px;height:20px;display:inline-block;margin-right:.5em;vertical-align:middle}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel],#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=text],#add_payment_method input.js-sv-wc-payment-gateway-echeck-form-input[type=tel],#add_payment_method input.js-sv-wc-payment-gateway-echeck-form-input[type=text],#add_payment_method input.js-sv-wc-payment-gateway-form-nickname,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel],.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=text],.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-echeck-form-input[type=tel],.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-echeck-form-input[type=text],.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-form-nickname{font-size:1.5em;padding:8px}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel]:focus,#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=text]:focus,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel]:focus,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=text]:focus{box-shadow:0 0 .1875em #3498db}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel].identified,#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=text].identified,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel].identified,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=text].identified{border-color:#69bf29}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel].identified:focus,#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-input[type=text].identified:focus,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=tel].identified:focus,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-input[type=text].identified:focus{box-shadow:0 0 .1875em #69bf29}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number{background-image:url(../../images/card-cc-plain.svg);background-repeat:no-repeat;background-position:right 10px center;background-size:50px 31px}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.visa,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.visa{background-image:url(../../images/card-visa.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.mastercard,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.mastercard{background-image:url(../../images/card-mastercard.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.dinersclub,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.dinersclub{background-image:url(../../images/card-dinersclub.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.maestro,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.maestro{background-image:url(../../images/card-maestro.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.jcb,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.jcb{background-image:url(../../images/card-jcb.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.amex,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.amex{background-image:url(../../images/card-amex.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.discover,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.discover{background-image:url(../../images/card-discover.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.visaelectron,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.visaelectron{background-image:url(../../images/card-visa-electron.svg)}#add_payment_method input.js-sv-wc-payment-gateway-credit-card-form-account-number.invalid-card-type,.woocommerce-checkout #payment div.payment_box input.js-sv-wc-payment-gateway-credit-card-form-account-number.invalid-card-type{background-image:url(../../images/card-cc-invalid.svg)}#add_payment_method .js-sv-wc-payment-gateway-echeck-form-check-hint,.woocommerce-checkout #payment div.payment_box .js-sv-wc-payment-gateway-echeck-form-check-hint{margin:0 0 3px 2px;cursor:pointer}#add_payment_method .js-sv-wc-payment-gateway-echeck-form-sample-check,.woocommerce-checkout #payment div.payment_box .js-sv-wc-payment-gateway-echeck-form-sample-check{margin:1em}#add_payment_method .js-sv-wc-payment-gateway-echeck-form-sample-check img,.woocommerce-checkout #payment div.payment_box .js-sv-wc-payment-gateway-echeck-form-sample-check img{min-height:135px}#add_payment_method ul.payment_methods li{list-style-type:none}#add_payment_method ul.payment_methods li img{vertical-align:middle;margin:-2px 0 0 .5em;padding:0;position:relative;box-shadow:none}#add_payment_method ul.payment_methods li img+img{margin-left:2px}
|
vendor/skyverge/wc-plugin-framework/tests/_archive/integration/plugin.php → assets/css/mixins.min.css
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/assets → assets}/css/mixins.scss
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amazon.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amazon.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amex.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-amex.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cartebleue.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cartebleue.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-invalid.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-invalid.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-plain.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cc-plain.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cirrus.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-cirrus.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-dinersclub.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-dinersclub.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-discover.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-discover.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-echeck.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-echeck.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-google.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-google.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-jcb.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-jcb.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-laser.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-laser.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-maestro.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-maestro.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-mastercard.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-mastercard.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-moneybookers.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-moneybookers.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-paypal.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-paypal.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-solo.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-solo.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-switch.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-switch.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-debit.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-debit.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-electron.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa-electron.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa.png
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/card-visa.svg
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/license.txt
RENAMED
File without changes
|
{vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/assets → assets}/images/sample-check.png
RENAMED
File without changes
|
assets/js/admin/wc-square-admin-products.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";jQuery(document).ready(function($){var typenow=window.typenow||"";var pagenow=window.pagenow||"";if("product"!==typenow){return}if(!wc_square_admin_products.is_product_sync_enabled){return}if("edit-product"===pagenow){$("#the-list").on("click",".editinline",function(e){var $row=$(e.target).closest("tr");var postID=$row.find("th.check-column input").val();var data={action:"wc_square_get_quick_edit_product_details",security:wc_square_admin_products.get_quick_edit_product_details_nonce,product_id:$row.find("th.check-column input").val()};$.post(wc_square_admin_products.ajax_url,data,function(response){var $editRow=$("tr#edit-"+postID);var $squareSynced=$editRow.find("select.square-synced");var $errors=$editRow.find(".wc-square-sync-with-square-errors");if(!response.success&&response.data){if("multiple_attributes"===response.data){$squareSynced.prop("checked",false);$squareSynced.prop("disabled",true);$errors.find(".multiple_attributes").show();return}else if("missing_variation_sku"===response.data){$squareSynced.prop("checked",false);$squareSynced.prop("disabled",true);$errors.find(".missing_variation_sku").show();return}}var $sku=$editRow.find("input[name=_sku]");var $stockStatus=$editRow.find("select[name=_stock_status]");var $stockQty=$editRow.find("input[name=_stock]");var $manageStockLabel=$editRow.find(".manage_stock_field .manage_stock");var $manageStockInput=$editRow.find("input[name=_manage_stock]");var $manageStockDesc="<span class=\"description\"><a href=\""+wc_square_admin_products.settings_url+"\">"+wc_square_admin_products.i18n.synced_with_square+"</a></span>";var edit_url=response.data.edit_url;var i18n=response.data.i18n;var is_variable=response.data.is_variable;$squareSynced.val(response.data.is_synced_with_square);$sku.on("change keyup keypress",function(e){if(""===$(e.target).val()&&!is_variable){$squareSynced.val("no").trigger("change");$squareSynced.prop("disabled",true);$errors.find(".missing_sku").show()}else{$squareSynced.prop("disabled",false);$squareSynced.trigger("change");return $errors.find(".missing_sku").hide()}}).trigger("change");$squareSynced.on("change",function(e){if("no"===$(e.target).val()){$manageStockInput.off();$manageStockInput.add($stockQty).css({opacity:1});$manageStockLabel.find(".description").remove();if(is_variable){if($manageStockInput.is(":checked")){$(".stock_qty_field").show();$(".backorder_field").show()}else{$(".stock_status_field").show()}}else{$stockQty.prop("readonly",false);$stockStatus.prop("readonly",false)}}else{$manageStockInput.prop("checked",true);$manageStockInput.on("click",function(){return false});$manageStockInput.add($stockQty).css({opacity:"0.5"});$manageStockLabel.append($manageStockDesc);if(wc_square_admin_products.is_woocommerce_sor&&edit_url&&i18n){$manageStockLabel.append("<p class=\"description\"><a href=\""+edit_url+"\">"+i18n+"</a></p>")}if(is_variable){$(".stock_status_field").hide();$(".stock_qty_field").hide();$(".backorder_field").hide()}else{$stockQty.prop("readonly",true);$stockStatus.prop("readonly",true)}}}).trigger("change")})})}if("product"===pagenow){var syncCheckboxID="#_"+wc_square_admin_products.synced_with_square_taxonomy;var isVariable=function isVariable(){return wc_square_admin_products.variable_product_types.includes($("#product-type").val())};var hasSKU=function hasSKU(){return""!==$("#_sku").val().trim()};var hasVariableSKUs=function hasVariableSKUs(skus){if(!skus.length){return false}var valid=skus.filter(function(sku){return""!==$(sku).val().trim()});return valid.length===skus.length};var hasUniqueSKUs=function hasUniqueSKUs(skus){var skuValues=skus.map(function(sku){return $(sku).val()});return skuValues.every(function(sku){return skuValues.indexOf(sku)===skuValues.lastIndexOf(sku)})};var hasMultipleAttributes=function hasMultipleAttributes(){var $variation_attributes=$(".woocommerce_attribute_data input[name^=\"attribute_variation\"]:checked");return isVariable()&&$variation_attributes&&$variation_attributes.length>1};var showError=function showError(error){$(".wc-square-sync-with-square-error."+error).show();$(syncCheckboxID).prop("disabled",true);$(syncCheckboxID).prop("checked",false)};var hideError=function hideError(error){var enable=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;$(".wc-square-sync-with-square-error."+error).hide();if(enable){$(syncCheckboxID).prop("disabled",false)}};var handleSKU=function handleSKU(syncCheckboxID){if(isVariable()){$("#_sku").off("change keypress keyup");hideError("missing_sku",!hasMultipleAttributes());var skus=$("input[id^=\"variable_sku\"]");skus.on("change keypress keyup",function(){if(!hasVariableSKUs($.makeArray(skus))||!hasUniqueSKUs($.makeArray(skus))){showError("missing_variation_sku")}else{hideError("missing_variation_sku",!hasMultipleAttributes())}$(syncCheckboxID).triggerHandler("change")}).triggerHandler("change")}else{$("input[id^=\"variable_sku\"]").off("change keypress keyup");hideError("missing_variation_sku",!hasMultipleAttributes());$("#_sku").on("change keypress keyup",function(e){if(""===$(e.target).val().trim()){showError("missing_sku")}else{hideError("missing_sku",!hasMultipleAttributes())}$(syncCheckboxID).trigger("change")}).trigger("change")}};var handleAttributes=function handleAttributes(syncCheckboxID){$("#variable_product_options").on("reload",function(){if(hasMultipleAttributes()){showError("multiple_attributes")}else{hideError("multiple_attributes",isVariable()?hasVariableSKUs:hasSKU())}$(syncCheckboxID).trigger("change")}).trigger("reload")};var triggerUpdate=function triggerUpdate(){handleSKU(syncCheckboxID);$(syncCheckboxID).trigger("change");if(isVariable()&&!$("input[id^=\"variable_sku\"]").length){showError("missing_variation_sku")}};handleAttributes(syncCheckboxID);var $stockFields=$(".stock_fields");var $stockInput=$stockFields.find("#_stock");var $stockStatus=$(".stock_status_field");var $manageField=$("._manage_stock_field");var $manageInput=$manageField.find("#_manage_stock");var $manageDesc=$manageField.find(".description");var manageDescOriginal=$manageDesc.text();var manageStockOriginal=$("#_manage_stock").is(":checked");$(syncCheckboxID).on("change",function(e){if(!wc_square_admin_products.is_inventory_sync_enabled){return}var variableProduct=wc_square_admin_products.variable_product_types.includes($("#product-type").val());var useSquare;if($(e.target).is(":checked")&&$("#_square_item_variation_id").length>0){useSquare=true;$manageDesc.html("<a href=\""+wc_square_admin_products.settings_url+"\">"+wc_square_admin_products.i18n.synced_with_square+"</a>");$manageInput.prop("disabled",true).prop("checked",!variableProduct);$stockFields.hide();$stockStatus.hide();$stockInput.prop("readonly",true);if(!variableProduct){$stockFields.show()}if(wc_square_admin_products.is_woocommerce_sor&&!variableProduct){if($("p._stock_field span.description").length===0){$stockInput.after("<span class=\"description\" style=\"display:block;clear:both;\"><a href=\"#\" id=\"fetch-stock-with-square\">"+wc_square_admin_products.i18n.fetch_stock_with_square+"</a><div class=\"spinner\" style=\"float:none;\"></div></span>")}$("#fetch-stock-with-square").on("click",function(e){e.preventDefault();var $spinner=$("p._stock_field span.description .spinner");var data={action:"wc_square_fetch_product_stock_with_square",security:wc_square_admin_products.fetch_product_stock_with_square_nonce,product_id:$("#post_ID").val()};$spinner.css("visibility","visible");$.post(wc_square_admin_products.ajax_url,data,function(response){if(response&&response.success){var quantity=response.data;$stockInput.val(quantity);$stockFields.find("input[name=_original_stock]").val(quantity);$stockInput.prop("readonly",false);$("p._stock_field span.description").remove()}else{if(response.data){$(".inventory-fetch-error").remove();$spinner.after("<span class=\"inventory-fetch-error\" style=\"display:inline-block;color:red;\">"+response.data+"</span>")}$spinner.css("visibility","hidden")}})})}else if(wc_square_admin_products.is_square_sor){if($("p._stock_field span.description").length===0){$stockInput.after("<span class=\"description\" style=\"display:block;clear:both;\">"+wc_square_admin_products.i18n.managed_by_square+"</span>")}}}else{useSquare=false;$("p._stock_field span.description").remove();$stockInput.prop("readonly",false);$manageDesc.html(manageDescOriginal);$manageInput.prop("disabled",false).prop("checked",manageStockOriginal);if(manageStockOriginal){$stockFields.show();$stockStatus.hide()}else{$stockStatus.show();$stockFields.hide()}}$(".woocommerce_variation").each(function(index,e){var variationID=$(e).find("h3 > a").attr("rel");var $variationManageInput=$(e).find(".variable_manage_stock");var $variationManageField=$variationManageInput.parent();var $variationStockInput=$(e).find(".wc_input_stock");var $variationStockField=$variationStockInput.parent();if(useSquare){$("#wc_square_variation_manage_stock").prop("disabled",false);$variationStockInput.prop("readonly",true);$variationManageInput.prop("disabled",true).prop("checked",true);if(0===$variationManageField.find(".description").length){$variationManageInput.after("<span class=\"description\">("+wc_square_admin_products.i18n.managed_by_square+")</span>")}if(wc_square_admin_products.is_woocommerce_sor){var fetchVariationStockActionID="fetch-stock-with-square-"+variationID;if(0===$variationStockField.find("span.description").length){$variationStockInput.after("<span class=\"description\" style=\"display:block;clear:both;\"><a href=\"#\" id=\""+fetchVariationStockActionID+"\">"+wc_square_admin_products.i18n.fetch_stock_with_square+"</a><div class=\"spinner\" style=\"float:none;\"></div></span>")}$("#"+fetchVariationStockActionID).on("click",function(e){e.preventDefault();var $spinner=$(e.target).next(".spinner");var data={action:"wc_square_fetch_product_stock_with_square",security:wc_square_admin_products.fetch_product_stock_with_square_nonce,product_id:variationID};$spinner.css("visibility","visible");$.post(wc_square_admin_products.ajax_url,data,function(response){if(response&&response.success){var quantity=response.data;$variationStockInput.val(quantity);$variationStockField.parent().find("input[name^=\"variable_original_stock\"]").val(quantity);$variationStockInput.prop("readonly",false);$variationStockField.find(".description").remove()}else{if(response.data){$(".inventory-fetch-error").remove();$spinner.after("<span class=\"inventory-fetch-error\" style=\"display:inline-block;color:red;\">"+response.data+"</span>")}$spinner.css("visibility","hidden")}})})}}else{$variationStockInput.prop("readonly",false);$variationManageInput.prop("disabled",false);$variationManageInput.next(".description").remove();$(e.target).find("#wc_square_variation_manage_stock").prop("disabled",true)}})}).trigger("change");$("#product-type").on("change",function(){triggerUpdate()});$("#woocommerce-product-data").on("woocommerce_variations_loaded woocommerce_variations_added woocommerce_variations_removed",function(){triggerUpdate()})}});
|
1 |
+
"use strict";jQuery(document).ready($=>{var typenow=window.typenow||"";var pagenow=window.pagenow||"";if("product"!==typenow){return}if(!wc_square_admin_products.is_product_sync_enabled){return}if("edit-product"===pagenow){$("#the-list").on("click",".editinline",e=>{var $row=$(e.target).closest("tr");var postID=$row.find("th.check-column input").val();var data={action:"wc_square_get_quick_edit_product_details",security:wc_square_admin_products.get_quick_edit_product_details_nonce,product_id:$row.find("th.check-column input").val()};$.post(wc_square_admin_products.ajax_url,data,response=>{var $editRow=$("tr#edit-"+postID);var $squareSynced=$editRow.find("select.square-synced");var $errors=$editRow.find(".wc-square-sync-with-square-errors");if(!response.success&&response.data){if("multiple_attributes"===response.data){$squareSynced.prop("checked",false);$squareSynced.prop("disabled",true);$errors.find(".multiple_attributes").show();return}else if("missing_variation_sku"===response.data){$squareSynced.prop("checked",false);$squareSynced.prop("disabled",true);$errors.find(".missing_variation_sku").show();return}}var $sku=$editRow.find("input[name=_sku]");var $stockStatus=$editRow.find("select[name=_stock_status]");var $stockQty=$editRow.find("input[name=_stock]");var $manageStockLabel=$editRow.find(".manage_stock_field .manage_stock");var $manageStockInput=$editRow.find("input[name=_manage_stock]");var $manageStockDesc="<span class=\"description\"><a href=\""+wc_square_admin_products.settings_url+"\">"+wc_square_admin_products.i18n.synced_with_square+"</a></span>";var edit_url=response.data.edit_url;var i18n=response.data.i18n;var is_variable=response.data.is_variable;$squareSynced.val(response.data.is_synced_with_square);$sku.on("change keyup keypress",e=>{if(""===$(e.target).val()&&!is_variable){$squareSynced.val("no").trigger("change");$squareSynced.prop("disabled",true);$errors.find(".missing_sku").show()}else{$squareSynced.prop("disabled",false);$squareSynced.trigger("change");return $errors.find(".missing_sku").hide()}}).trigger("change");$squareSynced.on("change",e=>{if("no"===$(e.target).val()){$manageStockInput.off();$manageStockInput.add($stockQty).css({opacity:1});$manageStockLabel.find(".description").remove();if(is_variable){if($manageStockInput.is(":checked")){$(".stock_qty_field").show();$(".backorder_field").show()}else{$(".stock_status_field").show()}}else{$stockQty.prop("readonly",false);$stockStatus.prop("readonly",false)}}else{$manageStockInput.prop("checked",true);$manageStockInput.on("click",()=>{return false});$manageStockInput.add($stockQty).css({opacity:"0.5"});$manageStockLabel.append($manageStockDesc);if(wc_square_admin_products.is_woocommerce_sor&&edit_url&&i18n){$manageStockLabel.append("<p class=\"description\"><a href=\""+edit_url+"\">"+i18n+"</a></p>")}if(is_variable){$(".stock_status_field").hide();$(".stock_qty_field").hide();$(".backorder_field").hide()}else{$stockQty.prop("readonly",true);$stockStatus.prop("readonly",true)}}}).trigger("change")})})}if("product"===pagenow){var syncCheckboxID="#_"+wc_square_admin_products.synced_with_square_taxonomy;var isVariable=()=>{return wc_square_admin_products.variable_product_types.includes($("#product-type").val())};var hasSKU=()=>{return""!==$("#_sku").val().trim()};var hasVariableSKUs=skus=>{if(!skus.length){return false}var valid=skus.filter(sku=>""!==$(sku).val().trim());return valid.length===skus.length};var hasUniqueSKUs=skus=>{var skuValues=skus.map(sku=>$(sku).val());return skuValues.every(sku=>skuValues.indexOf(sku)===skuValues.lastIndexOf(sku))};var hasMultipleAttributes=()=>{var $variation_attributes=$(".woocommerce_attribute_data input[name^=\"attribute_variation\"]:checked");return isVariable()&&$variation_attributes&&$variation_attributes.length>1};var showError=error=>{$(".wc-square-sync-with-square-error."+error).show();$(syncCheckboxID).prop("disabled",true);$(syncCheckboxID).prop("checked",false)};var hideError=function hideError(error){var enable=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;$(".wc-square-sync-with-square-error."+error).hide();if(enable){$(syncCheckboxID).prop("disabled",false)}};var handleSKU=syncCheckboxID=>{if(isVariable()){$("#_sku").off("change keypress keyup");hideError("missing_sku",!hasMultipleAttributes());var skus=$("input[id^=\"variable_sku\"]");skus.on("change keypress keyup",()=>{if(!hasVariableSKUs($.makeArray(skus))||!hasUniqueSKUs($.makeArray(skus))){showError("missing_variation_sku")}else{hideError("missing_variation_sku",!hasMultipleAttributes())}$(syncCheckboxID).triggerHandler("change")}).triggerHandler("change")}else{$("input[id^=\"variable_sku\"]").off("change keypress keyup");hideError("missing_variation_sku",!hasMultipleAttributes());$("#_sku").on("change keypress keyup",e=>{if(""===$(e.target).val().trim()){showError("missing_sku")}else{hideError("missing_sku",!hasMultipleAttributes())}$(syncCheckboxID).trigger("change")}).trigger("change")}};var handleAttributes=syncCheckboxID=>{$("#variable_product_options").on("reload",()=>{if(hasMultipleAttributes()){showError("multiple_attributes")}else{hideError("multiple_attributes",isVariable()?hasVariableSKUs:hasSKU())}$(syncCheckboxID).trigger("change")}).trigger("reload")};var triggerUpdate=()=>{handleSKU(syncCheckboxID);$(syncCheckboxID).trigger("change");if(isVariable()&&!$("input[id^=\"variable_sku\"]").length){showError("missing_variation_sku")}};handleAttributes(syncCheckboxID);var $stockFields=$(".stock_fields");var $stockInput=$stockFields.find("#_stock");var $stockStatus=$(".stock_status_field");var $manageField=$("._manage_stock_field");var $manageInput=$manageField.find("#_manage_stock");var $manageDesc=$manageField.find(".description");var manageDescOriginal=$manageDesc.text();var manageStockOriginal=$("#_manage_stock").is(":checked");$(syncCheckboxID).on("change",e=>{if(!wc_square_admin_products.is_inventory_sync_enabled){return}var variableProduct=wc_square_admin_products.variable_product_types.includes($("#product-type").val());var useSquare;if($(e.target).is(":checked")&&$("#_square_item_variation_id").length>0){useSquare=true;$manageDesc.html("<a href=\""+wc_square_admin_products.settings_url+"\">"+wc_square_admin_products.i18n.synced_with_square+"</a>");$manageInput.prop("disabled",true).prop("checked",!variableProduct);$stockFields.hide();$stockStatus.hide();$stockInput.prop("readonly",true);if(!variableProduct){$stockFields.show()}if(wc_square_admin_products.is_woocommerce_sor&&!variableProduct){if($("p._stock_field span.description").length===0){$stockInput.after("<span class=\"description\" style=\"display:block;clear:both;\"><a href=\"#\" id=\"fetch-stock-with-square\">"+wc_square_admin_products.i18n.fetch_stock_with_square+"</a><div class=\"spinner\" style=\"float:none;\"></div></span>")}$("#fetch-stock-with-square").on("click",e=>{e.preventDefault();var $spinner=$("p._stock_field span.description .spinner");var data={action:"wc_square_fetch_product_stock_with_square",security:wc_square_admin_products.fetch_product_stock_with_square_nonce,product_id:$("#post_ID").val()};$spinner.css("visibility","visible");$.post(wc_square_admin_products.ajax_url,data,response=>{if(response&&response.success){var quantity=response.data;$stockInput.val(quantity);$stockFields.find("input[name=_original_stock]").val(quantity);$stockInput.prop("readonly",false);$("p._stock_field span.description").remove()}else{if(response.data){$(".inventory-fetch-error").remove();$spinner.after("<span class=\"inventory-fetch-error\" style=\"display:inline-block;color:red;\">"+response.data+"</span>")}$spinner.css("visibility","hidden")}})})}else if(wc_square_admin_products.is_square_sor){if($("p._stock_field span.description").length===0){$stockInput.after("<span class=\"description\" style=\"display:block;clear:both;\">"+wc_square_admin_products.i18n.managed_by_square+"</span>")}}}else{useSquare=false;$("p._stock_field span.description").remove();$stockInput.prop("readonly",false);$manageDesc.html(manageDescOriginal);$manageInput.prop("disabled",false).prop("checked",manageStockOriginal);if(manageStockOriginal){$stockFields.show();$stockStatus.hide()}else{$stockStatus.show();$stockFields.hide()}}$(".woocommerce_variation").each((index,e)=>{var variationID=$(e).find("h3 > a").attr("rel");var $variationManageInput=$(e).find(".variable_manage_stock");var $variationManageField=$variationManageInput.parent();var $variationStockInput=$(e).find(".wc_input_stock");var $variationStockField=$variationStockInput.parent();if(useSquare){$("#wc_square_variation_manage_stock").prop("disabled",false);$variationStockInput.prop("readonly",true);$variationManageInput.prop("disabled",true).prop("checked",true);if(0===$variationManageField.find(".description").length){$variationManageInput.after("<span class=\"description\">("+wc_square_admin_products.i18n.managed_by_square+")</span>")}if(wc_square_admin_products.is_woocommerce_sor){var fetchVariationStockActionID="fetch-stock-with-square-"+variationID;if(0===$variationStockField.find("span.description").length){$variationStockInput.after("<span class=\"description\" style=\"display:block;clear:both;\"><a href=\"#\" id=\""+fetchVariationStockActionID+"\">"+wc_square_admin_products.i18n.fetch_stock_with_square+"</a><div class=\"spinner\" style=\"float:none;\"></div></span>")}$("#"+fetchVariationStockActionID).on("click",e=>{e.preventDefault();var $spinner=$(e.target).next(".spinner");var data={action:"wc_square_fetch_product_stock_with_square",security:wc_square_admin_products.fetch_product_stock_with_square_nonce,product_id:variationID};$spinner.css("visibility","visible");$.post(wc_square_admin_products.ajax_url,data,response=>{if(response&&response.success){var quantity=response.data;$variationStockInput.val(quantity);$variationStockField.parent().find("input[name^=\"variable_original_stock\"]").val(quantity);$variationStockInput.prop("readonly",false);$variationStockField.find(".description").remove()}else{if(response.data){$(".inventory-fetch-error").remove();$spinner.after("<span class=\"inventory-fetch-error\" style=\"display:inline-block;color:red;\">"+response.data+"</span>")}$spinner.css("visibility","hidden")}})})}}else{$variationStockInput.prop("readonly",false);$variationManageInput.prop("disabled",false);$variationManageInput.next(".description").remove();$(e.target).find("#wc_square_variation_manage_stock").prop("disabled",true)}})}).trigger("change");$("#product-type").on("change",()=>{triggerUpdate()});$("#woocommerce-product-data").on("woocommerce_variations_loaded woocommerce_variations_added woocommerce_variations_removed",()=>{triggerUpdate()})}});
|
assets/js/admin/wc-square-admin-settings.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";jQuery(document).ready(
|
1 |
+
"use strict";jQuery(document).ready($=>{var pagenow=window.pagenow||"";if("woocommerce_page_wc-settings"!==pagenow){return}if(!wc_square_admin_settings.is_sandbox){$("#wc_square_sandbox_settings").hide();$("#wc_square_sandbox_settings").next().hide();$(".wc_square_sandbox_settings").closest("tr").hide()}$("#wc_square_system_of_record").on("change",e=>{var system_of_record=$(e.target).val();var $inventory_sync=$("#wc_square_enable_inventory_sync");var $inventory_sync_row=$inventory_sync.closest("tr");if("square"===system_of_record||"woocommerce"===system_of_record){$inventory_sync.next("span").html(wc_square_admin_settings.i18n.sync_inventory_label[system_of_record]);$inventory_sync_row.find(".description").html(wc_square_admin_settings.i18n.sync_inventory_description[system_of_record]);$inventory_sync_row.show()}else{$inventory_sync.prop("checked",false);$inventory_sync_row.hide()}if("square"===system_of_record){$("#wc_square_hide_missing_products").closest("tr").show()}else{$("#wc_square_hide_missing_products").closest("tr").hide()}}).trigger("change");$(".js-import-square-products").on("click",e=>{e.preventDefault();new $.WCBackboneModal.View({target:"wc-square-import-products"});$("#btn-close").on("click",e=>{e.preventDefault();$("button.modal-close").trigger("click")})});$("#wc-square-sync").on("click",e=>{e.preventDefault();new $.WCBackboneModal.View({target:"wc-square-sync"});$("#btn-close").on("click",e=>{e.preventDefault();$("button.modal-close").trigger("click")})});$(document.body).on("wc_backbone_modal_response",(e,target)=>{var data;switch(target){case"wc-square-import-products":$("#wpbody").block({message:null,overlayCSS:{opacity:"0.2"},onBlock:function onBlock(){$(".blockUI.blockOverlay").css({position:"fixed"})}});var update_during_import=$("#wc-square-import-product-updates").prop("checked");data={action:"wc_square_import_products_from_square",security:wc_square_admin_settings.import_products_from_square,update_during_import};$.post(wc_square_admin_settings.ajax_url,data,response=>{var message=response.data?response.data:null;if(message){alert(message)}location.reload()});break;case"wc-square-sync":$("table.sync").block({message:null,overlayCSS:{opacity:"0.2"}});$("table.records").block({message:null,overlayCSS:{opacity:"0.2"}});$("#wc-square_clear-sync-records").prop("disabled",true);data={action:"wc_square_sync_products_with_square",security:wc_square_admin_settings.sync_products_with_square};$.post(wc_square_admin_settings.ajax_url,data,response=>{if(response&&response.success){location.reload()}else{$("#wc-square_clear-sync-records").prop("disabled",false);$("table.sync").unblock();$("table.records").unblock()}});break;}});var noRecordsFoundRow="<tr><td colspan=\"4\"><em>"+wc_square_admin_settings.i18n.no_records_found+"</em></td></tr>";$("#wc-square_clear-sync-records").on("click",e=>{e.preventDefault();$("table.records").block({message:null,overlayCSS:{opacity:"0.2"}});var data={action:"wc_square_handle_sync_records",id:"all",handle:"delete",security:wc_square_admin_settings.handle_sync_with_square_records};$.post(wc_square_admin_settings.ajax_url,data,response=>{if(response&&response.success){$("table.records tbody").html(noRecordsFoundRow);$("#wc-square_clear-sync-records").prop("disabled",true)}else{if(response.data){alert(response.data)}console.log(response)}$("table.records").unblock()})});$(".records .actions button.action").on("click",e=>{e.preventDefault();$("table.records").block({message:null,overlayCSS:{opacity:"0.2"}});var recordId=$(e.currentTarget).data("id");var action=$(e.currentTarget).data("action");var data={action:"wc_square_handle_sync_records",id:recordId,handle:action,security:wc_square_admin_settings.handle_sync_with_square_records};$.post(wc_square_admin_settings.ajax_url,data,response=>{if(response&&response.success){var rowId="#record-"+recordId;if("delete"===action){$(rowId).remove();if(!$("table.records tbody tr").length){$("table.records tbody").html(noRecordsFoundRow);$("#wc-square_clear-sync-records").prop("disabled",true)}}else if("resolve"===action||"unsync"===action){$(rowId+" .type").html("<mark class=\"resolved\"><span>"+wc_square_admin_settings.i18n.resolved+"</span></mark>");$(rowId+" .actions").html("—")}}else{if(response&&response.data){alert(response.data)}console.log({record:recordId,action,response})}$("table.records").unblock()})});$("form").on("submit",e=>{var environment=$("#wc_square_enable_sandbox").is(":checked")?"sandbox":"production";$(e.target).append($("<input>",{type:"hidden",name:"wc_square_environment",value:environment}))});var getSyncStatus=job_id=>{var $progress=$("span.progress");if(!$progress||0===$progress.length){$("p.sync-result").append(" <span class=\"progress\" style=\"display:block\"></span>");$progress=$("span.progress")}var data={action:"wc_square_get_sync_with_square_status",security:wc_square_admin_settings.get_sync_with_square_status_nonce,job_id};$.post(wc_square_admin_settings.ajax_url,data,response=>{if(response&&response.data){if(response.success&&response.data.id){$("table.sync .spinner").css("visibility","visible");$("#wc-square_clear-sync-records").prop("disabled",true);$("table.records .actions button").prop("disabled",true);if("completed"!==response.data.status&&"failed"!==response.data.status){var progress=" ";if("product_import"===response.data.action){progress+=wc_square_admin_settings.i18n.skipped+": "+parseInt(response.data.skipped_products_count,10)+"<br/>";progress+=wc_square_admin_settings.i18n.updated+": "+parseInt(response.data.updated_products_count,10)+"<br/>";progress+=wc_square_admin_settings.i18n.imported+": "+parseInt(response.data.imported_products_count,10)}else if(response.data.percentage){progress+=parseInt(response.data.percentage,10)+"%"}$progress.html(progress);setTimeout(()=>{getSyncStatus(response.data.id)},30*1000)}else{location.reload()}}else{$("#wc-square_clear-sync-records").prop("disabled",false);$("table.records .actions button").prop("disabled",false);$("table.sync .spinner").css("visibility","hidden");console.log(response)}}})};if(wc_square_admin_settings.existing_sync_job_id){getSyncStatus(wc_square_admin_settings.existing_sync_job_id)}$("#woocommerce_square_credit_card_enable_digital_wallets").on("change",()=>{var wallet_settings=$(".wc-square-digital-wallet-options");if($("#woocommerce_square_credit_card_enable_digital_wallets").is(":checked")){wallet_settings.closest("tr").show()}else{wallet_settings.closest("tr").hide()}}).trigger("change")});
|
assets/js/admin/wc-square-payment-gateway-admin-order.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";(function(){jQuery(document).ready(function($){"use strict";var accounting,ref,ref1,ref2,ref3,submitCapture,sv_wc_payment_gateway_admin_order,woocommerce_admin,woocommerce_admin_meta_boxes;sv_wc_payment_gateway_admin_order=(ref=window.sv_wc_payment_gateway_admin_order)!=null?ref:{};woocommerce_admin=(ref1=window.woocommerce_admin)!=null?ref1:{};woocommerce_admin_meta_boxes=(ref2=window.woocommerce_admin_meta_boxes)!=null?ref2:{};accounting=(ref3=window.accounting)!=null?ref3:{};$(".sv-wc-payment-gateway-partial-capture").appendTo("#woocommerce-order-items .inside");$("#woocommerce-order-items").on("click",".wc-square-payment-gateway-capture:not(.disabled)",function(e){e.preventDefault();if($(this).hasClass("partial-capture")){$("div.sv-wc-payment-gateway-partial-capture").slideDown();$("div.wc-order-data-row-toggle").not("div.sv-wc-payment-gateway-partial-capture").slideUp();return $("div.wc-order-totals-items").slideUp()}return submitCapture()});$(".sv-wc-payment-gateway-partial-capture").on("change keyup","#capture_amount",function(e){var total;total=accounting.unformat($(this).val(),woocommerce_admin.mon_decimal_point);if(total){$("button.capture-action").removeAttr("disabled")}else{$("button.capture-action").attr("disabled","disabled")}return $("button .capture-amount .amount").text(accounting.formatMoney(total,{symbol:woocommerce_admin_meta_boxes.currency_format_symbol,decimal:woocommerce_admin_meta_boxes.currency_format_decimal_sep,thousand:woocommerce_admin_meta_boxes.currency_format_thousand_sep,precision:woocommerce_admin_meta_boxes.currency_format_num_decimals,format:woocommerce_admin_meta_boxes.currency_format}))});$(".sv-wc-payment-gateway-partial-capture").on("click",".capture-action",function(e){var amount,comment;e.preventDefault();amount=$(".sv-wc-payment-gateway-partial-capture #capture_amount").val();comment=$(".sv-wc-payment-gateway-partial-capture #capture_comment").val();return submitCapture(amount,comment)});return submitCapture=function submitCapture(amount,comment){var data;if(amount==null){amount=""}if(comment==null){comment=""}if(confirm(sv_wc_payment_gateway_admin_order.capture_ays)){$("#woocommerce-order-items").block({message:null,overlayCSS:{background:"#fff",opacity:0.6}});data={action:sv_wc_payment_gateway_admin_order.capture_action,nonce:sv_wc_payment_gateway_admin_order.capture_nonce,gateway_id:sv_wc_payment_gateway_admin_order.gateway_id,order_id:sv_wc_payment_gateway_admin_order.order_id,amount,comment};return $.ajax({url:sv_wc_payment_gateway_admin_order.ajax_url,data}).done(function(response){if(response.data!=null&&response.data.message!=null){alert(response.data.message)}if(response.success){return location.reload()}}).fail(function(){return alert(sv_wc_payment_gateway_admin_order.capture_error)}).always(function(){return $("#woocommerce-order-items").unblock()})}}})}).call(void 0);
|
assets/js/admin/wc-square-payment-gateway-token-editor.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";(function(){jQuery(document).ready(function($){"use strict";var handleError,ref,wc_payment_gateway_token_editor;wc_payment_gateway_token_editor=(ref=window.wc_payment_gateway_token_editor)!=null?ref:{};$(".sv_wc_payment_gateway_token_editor").each(function(){var tokens;tokens=$(this).find("tr.token");if(tokens.length===0){return $(this).find("tr.no-tokens").show()}return $(this).find("tr.no-tokens").hide()});$(".sv_wc_payment_gateway_token_editor").on("click",".button[data-action=\"remove\"]",function(e){var data,editor,row;e.preventDefault();if(!confirm(wc_payment_gateway_token_editor.actions.remove_token.ays)){return}editor=$(this).closest("table");editor.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}});editor.find(".error").remove();row=$(this).closest("tr");if(row.hasClass("new-token")){return row.remove()}data={action:"wc_payment_gateway_"+editor.data("gateway-id")+"_admin_remove_payment_token",user_id:$(this).data("user-id"),token_id:$(this).data("token-id"),security:wc_payment_gateway_token_editor.actions.remove_token.nonce};return $.post(wc_payment_gateway_token_editor.ajax_url,data).done(function(_this){return function(response){if(!response.success){return handleError(editor,response.data)}$(row).remove();if(editor.find("tr.token").length===0){return editor.find("tr.no-tokens").show()}}}(this)).fail(function(_this){return function(jqXHR,textStatus,error){return handleError(editor,textStatus+": "+error)}}(this)).always(function(_this){return function(){return editor.unblock()}}(this))});$("table.sv_wc_payment_gateway_token_editor").on("click",".button[data-action=\"add-new\"]",function(e){var body,count,data,editor;e.preventDefault();editor=$(this).closest("table");editor.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}});body=editor.find("tbody.tokens");count=body.find("tr.token").length;data={action:"wc_payment_gateway_"+editor.data("gateway-id")+"_admin_get_blank_payment_token",index:count+1,security:wc_payment_gateway_token_editor.actions.add_token.nonce};return $.post(wc_payment_gateway_token_editor.ajax_url,data,function(response){if(response.success===true){body.append(response.data)}editor.find("tr.no-tokens").hide();return editor.unblock()})});$("table.sv_wc_payment_gateway_token_editor").on("click",".button[data-action=\"refresh\"]",function(e){var body,count,data,editor;e.preventDefault();editor=$(this).closest("table");editor.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}});editor.find(".error").remove();body=editor.find("tbody.tokens");count=body.find("tr.token").length;data={action:"wc_payment_gateway_"+editor.data("gateway-id")+"_admin_refresh_payment_tokens",user_id:$(this).data("user-id"),security:wc_payment_gateway_token_editor.actions.refresh.nonce};return $.post(wc_payment_gateway_token_editor.ajax_url,data).done(function(_this){return function(response){if(!response.success){return handleError(editor,response.data)}if(response.data!=null){editor.find("tr.no-tokens").hide();return body.html(response.data)}body.empty();return editor.find("tr.no-tokens").show()}}(this)).fail(function(_this){return function(jqXHR,textStatus,error){return handleError(editor,textStatus+": "+error)}}(this)).always(function(_this){return function(){return editor.unblock()}}(this))});$("table.sv_wc_payment_gateway_token_editor").on("click",".sv-wc-payment-gateway-token-editor-action-button[data-action=\"save\"]",function(e){var actions_row,editor,focused,inputs;editor=$(this).closest("table");actions_row=editor.find("tfoot th");editor.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}});actions_row.find(".error, .success").remove();inputs=editor.find("tbody.tokens tr.token input[type=\"text\"]");focused=false;return inputs.each(function(index){var pattern,required,value;$(this).removeClass("error");value=$(this).val();required=$(this).prop("required");pattern=$(this).attr("pattern");if(!(required||value)){return}if(!value.match(pattern)||required&&!value){e.preventDefault();$(this).addClass("error");if(!focused){actions_row.prepend("<span class=\"error\">"+wc_payment_gateway_token_editor.actions.save.error+"</span>");$(this).focus();focused=true}return editor.unblock()}})});return handleError=function handleError(editor,error,message){if(message==null){message=""}console.error(error);if(!message){message=wc_payment_gateway_token_editor.i18n.general_error}return editor.find("th.actions").prepend("<span class=\"error\">"+message+"</span>")}})}).call(void 0);
|
assets/js/frontend/wc-square-digital-wallet.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor}jQuery(document).ready(function($){var WC_Square_Digital_Wallet_Handler=function(){function WC_Square_Digital_Wallet_Handler(args){_classCallCheck(this,WC_Square_Digital_Wallet_Handler);this.args=args;this.payment_request=args.payment_request;this.total_amount=args.payment_request.total.amount;this.wallet="#wc-square-digital-wallet";this.buttons=".wc-square-wallet-buttons";if($(this.wallet).length===0){return}$(this.wallet).hide();$(this.buttons).hide();this.build_digital_wallet();this.attach_page_events()}_createClass(WC_Square_Digital_Wallet_Handler,[{key:"build_digital_wallet",value:function build_digital_wallet(){var _this=this;this.block_ui();this.get_payment_request().then(function(response){_this.payment_request=JSON.parse(response);_this.total_amount=_this.payment_request.total.amount;_this.load_square_form();_this.unblock_ui()},function(message){_this.log("[Square] Could not build payment request. "+message,"error");$(_this.wallet).hide()})}},{key:"attach_page_events",value:function attach_page_events(){var _this2=this;if(this.args.context==="product"){var addToCartButton=$(".single_add_to_cart_button");$("#wc-square-apple-pay, #wc-square-google-pay").on("click",function(e){if(addToCartButton.is(".disabled")){e.stopImmediatePropagation();if(addToCartButton.is(".wc-variation-is-unavailable")){window.alert(wc_add_to_cart_variation_params.i18n_unavailable_text)}else if(addToCartButton.is(".wc-variation-selection-needed")){window.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text)}return}_this2.add_to_cart()});$(document.body).on("woocommerce_variation_has_changed",function(){return _this2.build_digital_wallet()});$(".quantity").on("input",".qty",function(){return _this2.build_digital_wallet()})}if(this.args.context==="cart"){$(document.body).on("updated_cart_totals",function(){return _this2.build_digital_wallet()})}if(this.args.context==="checkout"){$(document.body).on("updated_checkout",function(){return _this2.build_digital_wallet()})}}},{key:"load_square_form",value:function load_square_form(){if(this.payment_form){this.log("[Square] Destroying digital wallet payment form");this.payment_form.destroy()}this.log("[Square] Building digital wallet payment form");this.payment_form=new SqPaymentForm(this.get_form_params());this.payment_form.build()}},{key:"get_form_params",value:function get_form_params(){var _this3=this;var params={applicationId:this.args.application_id,locationId:this.args.location_id,autobuild:false,applePay:{elementId:"wc-square-apple-pay"},googlePay:{elementId:"wc-square-google-pay"},callbacks:{paymentFormLoaded:function paymentFormLoaded(){return _this3.unblock_ui()},createPaymentRequest:function createPaymentRequest(){return _this3.create_payment_request()},methodsSupported:function methodsSupported(methods,unsupportedReason){return _this3.methods_supported(methods,unsupportedReason)},shippingContactChanged:function shippingContactChanged(shippingContact,done){return _this3.handle_shipping_address_changed(shippingContact,done)},shippingOptionChanged:function shippingOptionChanged(shippingOption,done){return _this3.handle_shipping_option_changed(shippingOption,done)},cardNonceResponseReceived:function cardNonceResponseReceived(errors,nonce,cardData,billingContact,shippingContact,shippingOption){_this3.handle_card_nonce_response(errors,nonce,cardData,billingContact,shippingContact,shippingOption)}}};if(this.payment_request.requestShippingAddress===false){delete params.callbacks.shippingOptionChanged}if(this.args.hide_button_options.includes("google")){delete params.googlePay}if(this.args.hide_button_options.includes("apple")){delete params.applePay}return params}},{key:"create_payment_request",value:function create_payment_request(){return this.payment_request}},{key:"methods_supported",value:function methods_supported(methods,unsupportedReason){if(methods.applePay===true||methods.googlePay===true){if(methods.applePay===true){$("#wc-square-apple-pay").show()}if(methods.googlePay===true){$("#wc-square-google-pay").show()}$(this.wallet).show()}else{this.log(unsupportedReason)}}},{key:"get_payment_request",value:function get_payment_request(){var _this4=this;return new Promise(function(resolve,reject){var data={context:_this4.args.context,security:_this4.args.payment_request_nonce};if(_this4.args.context==="product"){var product_data=_this4.get_product_data();$.extend(data,product_data)}$.post(_this4.get_ajax_url("get_payment_request"),data,function(response){if(response.success){return resolve(response.data)}return reject(response.data)})})}},{key:"handle_shipping_address_changed",value:function handle_shipping_address_changed(shippingContact,done){var data={context:this.args.context,shipping_contact:shippingContact.data,security:this.args.recalculate_totals_nonce};this.recalculate_totals(data).then(function(response){return done(response)},function(){return done({error:"Bad Request"})})}},{key:"handle_shipping_option_changed",value:function handle_shipping_option_changed(shippingOption,done){var data={context:this.args.context,shipping_option:shippingOption.data.id,security:this.args.recalculate_totals_nonce};this.recalculate_totals(data).then(function(response){return done(response)},function(){return done({error:"Bad Request"})})}},{key:"handle_card_nonce_response",value:function handle_card_nonce_response(errors,nonce,cardData,billingContact,shippingContact,shippingOption){if(errors){return this.render_errors(errors)}if(!nonce){return this.render_errors(this.args.general_error)}this.block_ui();var data={action:"",_wpnonce:this.args.process_checkout_nonce,billing_first_name:billingContact.givenName?billingContact.givenName:"",billing_last_name:billingContact.familyName?billingContact.familyName:"",billing_company:"",billing_email:shippingContact.email?shippingContact.email:"",billing_phone:shippingContact.phone?shippingContact.phone:"",billing_country:billingContact.country?billingContact.country.toUpperCase():"",billing_address_1:billingContact.addressLines&&billingContact.addressLines[0]?billingContact.addressLines[0]:"",billing_address_2:billingContact.addressLines&&billingContact.addressLines[1]?billingContact.addressLines[1]:"",billing_city:billingContact.city?billingContact.city:"",billing_state:billingContact.region?billingContact.region:"",billing_postcode:billingContact.postalCode?billingContact.postalCode:"",shipping_first_name:shippingContact.givenName?shippingContact.givenName:"",shipping_last_name:shippingContact.familyName?shippingContact.familyName:"",shipping_company:"",shipping_country:shippingContact.country?shippingContact.country.toUpperCase():"",shipping_address_1:shippingContact.addressLines&&shippingContact.addressLines[0]?shippingContact.addressLines[0]:"",shipping_address_2:shippingContact.addressLines&&shippingContact.addressLines[1]?shippingContact.addressLines[1]:"",shipping_city:shippingContact.city?shippingContact.city:"",shipping_state:shippingContact.region?shippingContact.region:"",shipping_postcode:shippingContact.postalCode?shippingContact.postalCode:"",shipping_method:[!shippingOption?null:shippingOption.id],order_comments:"",payment_method:"square_credit_card",ship_to_different_address:1,terms:1,"wc-square-credit-card-payment-nonce":nonce,"wc-square-credit-card-last-four":cardData.last_4?cardData.last_4:null,"wc-square-credit-card-exp-month":cardData.exp_month?cardData.exp_month:null,"wc-square-credit-card-exp-year":cardData.exp_year?cardData.exp_year:null,"wc-square-credit-card-payment-postcode":cardData.billing_postal_code?cardData.billing_postal_code:null,"wc-square-digital-wallet-type":cardData.digital_wallet_type};if(cardData.digital_wallet_type==="GOOGLE_PAY"){if(billingContact.givenName){data.billing_first_name=billingContact.givenName.split(" ").slice(0,1).join(" ");data.billing_last_name=billingContact.givenName.split(" ").slice(1).join(" ")}if(shippingContact.givenName){data.shipping_last_name=shippingContact.givenName.split(" ").slice(0,1).join(" ");data.shipping_last_name=shippingContact.givenName.split(" ").slice(1).join(" ")}}if(!data.billing_phone&&billingContact.phone){data.billing_phone=billingContact.phone}if(this.args.is_3d_secure_enabled){this.log("3DS verification enabled. Verifying buyer");var self=this;this.payment_form.verifyBuyer(nonce,self.get_verification_details(billingContact,shippingContact),function(err,verificationResult){if(err==null){self.log("3DS verification successful");data["wc-square-credit-card-buyer-verification-token"]=verificationResult.token;self.do_checkout(data)}else{self.log("3DS verification failed");self.log(err);self.render_errors([err.message])}})}else{this.do_checkout(data)}}},{key:"do_checkout",value:function do_checkout(data){var _this5=this;this.process_digital_wallet_checkout(data).then(function(response){window.location=response.redirect},function(response){_this5.log(response,"error");_this5.render_errors_html(response.messages)})}},{key:"get_verification_details",value:function get_verification_details(billingContact,shippingContact){var verification_details={intent:"CHARGE",amount:this.total_amount,currencyCode:this.payment_request.currencyCode,billingContact:{familyName:billingContact.familyName?billingContact.familyName:"",givenName:billingContact.givenName?billingContact.givenName:"",email:shippingContact.email?shippingContact.email:"",country:billingContact.country?billingContact.country.toUpperCase():"",region:billingContact.region?billingContact.region:"",city:billingContact.city?billingContact.city:"",postalCode:billingContact.postalCode?billingContact.postalCode:"",phone:shippingContact.phone?shippingContact.phone:"",addressLines:billingContact.addressLines?billingContact.addressLines:""}};this.log(verification_details);return verification_details}},{key:"recalculate_totals",value:function recalculate_totals(data){var _this6=this;return new Promise(function(resolve,reject){return $.post(_this6.get_ajax_url("recalculate_totals"),data,function(response){if(response.success){_this6.total_amount=response.data.total.amount;return resolve(response.data)}return reject(response.data)})})}},{key:"get_product_data",value:function get_product_data(){var product_id=$(".single_add_to_cart_button").val();var attributes={};if($(".single_variation_wrap").length){product_id=$(".single_variation_wrap").find("input[name=\"product_id\"]").val();if($(".variations_form").length){$(".variations_form").find(".variations select").each(function(index,select){var attribute_name=$(select).data("attribute_name")||$(select).attr("name");var value=$(select).val()||"";return attributes[attribute_name]=value})}}return{product_id:product_id,quantity:$(".quantity .qty").val(),attributes:attributes}}},{key:"add_to_cart",value:function add_to_cart(){var _this7=this;var data={security:this.args.add_to_cart_nonce};var product_data=this.get_product_data();$.extend(data,product_data);$.post(this.get_ajax_url("add_to_cart"),data,function(response){if(response.error){return window.alert(response.data)}var data=JSON.parse(response.data);_this7.payment_request=data.payment_request;_this7.args.payment_request_nonce=data.payment_request_nonce;_this7.args.add_to_cart_nonce=data.add_to_cart_nonce;_this7.args.recalculate_totals_nonce=data.recalculate_totals_nonce;_this7.args.process_checkout_nonce=data.process_checkout_nonce})}},{key:"process_digital_wallet_checkout",value:function process_digital_wallet_checkout(data){var _this8=this;return new Promise(function(resolve,reject){$.post(_this8.get_ajax_url("process_checkout"),data,function(response){if(response.result==="success"){return resolve(response)}return reject(response)})})}},{key:"get_ajax_url",value:function get_ajax_url(request){return this.args.ajax_url.replace("%%endpoint%%","square_digital_wallet_"+request)}},{key:"render_errors_html",value:function render_errors_html(errors_html){$(".woocommerce-error, .woocommerce-message").remove();var element=this.args.context==="product"?$(".product"):$(".shop_table.cart").closest("form");element.before(errors_html);this.unblock_ui();$("html, body").animate({scrollTop:element.offset().top-100},1000)}},{key:"render_errors",value:function render_errors(errors){var error_message_html="<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>";this.render_errors_html(error_message_html)}},{key:"block_ui",value:function block_ui(){$(this.buttons).block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})}},{key:"unblock_ui",value:function unblock_ui(){$(this.buttons).unblock()}},{key:"log",value:function log(message){var type=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"notice";if(!this.args.logging_enabled){return}if(type==="error"){return console.error(message)}return console.log(message)}}]);return WC_Square_Digital_Wallet_Handler}();window.WC_Square_Digital_Wallet_Handler=WC_Square_Digital_Wallet_Handler});
|
1 |
+
"use strict";function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);enumerableOnly&&(symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})),keys.push.apply(keys,symbols)}return keys}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=null!=arguments[i]?arguments[i]:{};i%2?ownKeys(Object(source),!0).forEach(function(key){_defineProperty(target,key,source[key])}):Object.getOwnPropertyDescriptors?Object.defineProperties(target,Object.getOwnPropertyDescriptors(source)):ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}return target}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}jQuery(document).ready($=>{class WC_Square_Digital_Wallet_Handler{constructor(args){this.args=args;this.payment_request=args.payment_request;this.total_amount=args.payment_request.total.amount;this.cartForm=".cart";this.wallet="#wc-square-digital-wallet";this.buttons=".wc-square-wallet-buttons";this.isGooglePayHidden=this.args.hide_button_options.includes("google");this.isApplePayHidden=this.args.hide_button_options.includes("apple");if($(this.wallet).length===0){return}$(this.wallet).hide();$(this.buttons).hide();this.build_digital_wallet();this.attach_page_events();this.buildDigitalWalletDebounced=this.debounce(this.build_digital_wallet,500)}build_digital_wallet(){this.block_ui();this.get_payment_request().then(response=>{this.payment_request=JSON.parse(response);this.total_amount=this.payment_request.total.amount;this.load_square_form()},message=>{this.log("[Square] Could not build payment request. "+message,"error");$(this.wallet).hide()})}attach_page_events(){if(this.args.context==="product"){var addToCartButton=$(".single_add_to_cart_button");$("#apple-pay-button, #wc-square-google-pay").on("click",e=>{if(addToCartButton.is(".disabled")){e.stopImmediatePropagation();if(addToCartButton.is(".wc-variation-is-unavailable")){window.alert(wc_add_to_cart_variation_params.i18n_unavailable_text)}else if(addToCartButton.is(".wc-variation-selection-needed")){window.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text)}return}this.add_to_cart()});$(document.body).on("woocommerce_variation_has_changed",()=>this.build_digital_wallet());$(".quantity").on("input",".qty",()=>this.build_digital_wallet())}if(this.args.context==="cart"){$(document.body).on("updated_cart_totals",()=>this.build_digital_wallet())}if(this.args.context==="checkout"){$(document.body).on("updated_checkout",()=>this.build_digital_wallet())}}load_square_form(){if(this.googlePay){this.googlePay.destroy();this.squareFormLoaded=false}if(this.applePay){this.applePay.destroy();this.squareFormLoaded=false}if(this.squareFormLoaded){return}this.squareFormLoaded=true;this.log("[Square] Building digital wallet payment form");var{applicationId,locationId}=this.get_form_params();this.payments=window.Square.payments(applicationId,locationId);this.initializeDigitalWalletPaymentMethods()}initializeDigitalWalletPaymentMethods(){var _this=this;return _asyncToGenerator(function*(){if(!_this.payments){return}var paymentRequest=_this.payments.paymentRequest(_this.create_payment_request());_this.registerDigitalWalletShippingEventHandlers(paymentRequest);if(!_this.isGooglePayHidden){_this.googlePay=yield _this.payments.googlePay(paymentRequest);_this.googlePay.attach("#wc-square-google-pay",{buttonSizeMode:"fill",buttonType:"long",buttonColor:_this.args.google_pay_color});$("#wc-square-google-pay").on("click",function(){var _ref=_asyncToGenerator(function*(e){return _this.handleGooglePayPaymentMethodSubmission(e,_this.googlePay)});return function(_x){return _ref.apply(this,arguments)}}());$("#wc-square-google-pay").show()}if(!_this.isApplePayHidden){try{_this.applePay=yield _this.payments.applePay(paymentRequest);$("#apple-pay-button").on("click",function(){var _ref2=_asyncToGenerator(function*(e){return _this.handleApplePayPaymentMethodSubmission(e,_this.applePay)});return function(_x2){return _ref2.apply(this,arguments)}}());$("#apple-pay-button").show()}catch(e){console.log(e.message)}}if(_this.googlePay||_this.applePay){$(_this.wallet).show();_this.unblock_ui()}})()}handleGooglePayPaymentMethodSubmission(e){var _arguments=arguments,_this2=this;return _asyncToGenerator(function*(){var googlePay=_arguments.length>1&&_arguments[1]!==undefined?_arguments[1]:null;e.preventDefault();if(!googlePay){return}var result=yield googlePay.tokenize();if(result.status==="OK"){var cardData=_objectSpread(_objectSpread({},result.details.card),{},{digital_wallet_type:result.details.method});var billingAndShippingData={billingContact:result.details.billing};if(result.details.shipping){billingAndShippingData.shippingContact=result.details.shipping.contact;billingAndShippingData.shippingOption=result.details.shipping.option}_this2.handle_card_nonce_response(false,result.token,cardData,billingAndShippingData)}})()}handleApplePayPaymentMethodSubmission(e){var _arguments2=arguments,_this3=this;return _asyncToGenerator(function*(){var applePay=_arguments2.length>1&&_arguments2[1]!==undefined?_arguments2[1]:null;e.preventDefault();if(!applePay){return}var result=yield applePay.tokenize();if(result.status==="OK"){var cardData=_objectSpread(_objectSpread({},result.details.card),{},{digital_wallet_type:result.details.method});var billingAndShippingData={billingContact:result.details.billing};if(result.details.shipping){billingAndShippingData.shippingContact=result.details.shipping.contact;billingAndShippingData.shippingOption=result.details.shipping.option}_this3.handle_card_nonce_response(false,result.token,cardData,billingAndShippingData)}})()}registerDigitalWalletShippingEventHandlers(paymentRequest){paymentRequest.addEventListener("shippingoptionchanged",option=>this.handle_shipping_option_changed(option));paymentRequest.addEventListener("shippingcontactchanged",shippingContact=>this.handle_shipping_address_changed(shippingContact))}get_form_params(){var params={applicationId:this.args.application_id,locationId:this.args.location_id,autobuild:false,applePay:{elementId:"apple-pay-button"},googlePay:{elementId:"wc-square-google-pay"}};if(this.payment_request.requestShippingAddress===false){delete params.callbacks.shippingOptionChanged}if(this.args.hide_button_options.includes("google")){delete params.googlePay}if(this.args.hide_button_options.includes("apple")){delete params.applePay}return params}create_payment_request(){return this.payment_request}methods_supported(methods,unsupportedReason){if(methods.applePay===true||methods.googlePay===true){if(methods.applePay===true){$("#apple-pay-button").show()}if(methods.googlePay===true){$("#wc-square-google-pay").show()}$(this.wallet).show()}else{this.log(unsupportedReason)}}get_payment_request(){return new Promise((resolve,reject)=>{var data={context:this.args.context,security:this.args.payment_request_nonce};if(this.args.context==="product"){var product_data=this.get_product_data();$.extend(data,product_data)}$.post(this.get_ajax_url("get_payment_request"),data,response=>{if(response.success){return resolve(response.data)}return reject(response.data)})})}handle_shipping_address_changed(shippingContact){var _this4=this;return _asyncToGenerator(function*(){var data={context:_this4.args.context,shipping_contact:shippingContact,security:_this4.args.recalculate_totals_nonce};var response=yield _this4.recalculate_totals(data);return response})()}handle_shipping_option_changed(shippingOption){var _this5=this;return _asyncToGenerator(function*(){var data={context:_this5.args.context,shipping_option:shippingOption.id,security:_this5.args.recalculate_totals_nonce};var response=yield _this5.recalculate_totals(data);return response})()}handle_card_nonce_response(){var errors=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;var nonce=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;var cardData=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var billingAndShippingData=arguments.length>3&&arguments[3]!==undefined?arguments[3]:{};if(errors){return this.render_errors(errors)}if(!nonce){return this.render_errors(this.args.general_error)}this.block_ui();var{billingContact={},shippingContact={},shippingOption=null}=billingAndShippingData;var data={action:"",_wpnonce:this.args.process_checkout_nonce,billing_first_name:billingContact.givenName?billingContact.givenName:"",billing_last_name:billingContact.familyName?billingContact.familyName:"",billing_company:"",billing_email:shippingContact.email?shippingContact.email:billingContact.email?billingContact.email:"",billing_phone:shippingContact.phone?shippingContact.phone:"",billing_country:billingContact.countryCode?billingContact.countryCode.toUpperCase():"",billing_address_1:billingContact.addressLines&&billingContact.addressLines[0]?billingContact.addressLines[0]:"",billing_address_2:billingContact.addressLines&&billingContact.addressLines[1]?billingContact.addressLines[1]:"",billing_city:billingContact.city?billingContact.city:"",billing_state:billingContact.state?billingContact.state:"",billing_postcode:billingContact.postalCode?billingContact.postalCode:"",shipping_first_name:shippingContact.givenName?shippingContact.givenName:"",shipping_last_name:shippingContact.familyName?shippingContact.familyName:"",shipping_company:"",shipping_country:shippingContact.countryCode?shippingContact.countryCode.toUpperCase():"",shipping_address_1:shippingContact.addressLines&&shippingContact.addressLines[0]?shippingContact.addressLines[0]:"",shipping_address_2:shippingContact.addressLines&&shippingContact.addressLines[1]?shippingContact.addressLines[1]:"",shipping_city:shippingContact.city?shippingContact.city:"",shipping_state:shippingContact.state?shippingContact.state:"",shipping_postcode:shippingContact.postalCode?shippingContact.postalCode:"",shipping_method:[!shippingOption?null:shippingOption.id],order_comments:"",payment_method:"square_credit_card",ship_to_different_address:1,terms:1,"wc-square-credit-card-payment-nonce":nonce,"wc-square-credit-card-last-four":cardData.last4?cardData.last4:null,"wc-square-credit-card-exp-month":cardData.expMonth?cardData.expMonth:null,"wc-square-credit-card-exp-year":cardData.expYear?cardData.expYear:null,"wc-square-credit-card-payment-postcode":cardData.billing.postalCode?cardData.billing.postalCode:null,"wc-square-digital-wallet-type":cardData.digital_wallet_type};if(cardData.digital_wallet_type==="GOOGLE_PAY"){if(billingContact.givenName){data.billing_first_name=billingContact.givenName.split(" ").slice(0,1).join(" ");data.billing_last_name=billingContact.givenName.split(" ").slice(1).join(" ")}if(shippingContact.givenName){data.shipping_last_name=shippingContact.givenName.split(" ").slice(0,1).join(" ");data.shipping_last_name=shippingContact.givenName.split(" ").slice(1).join(" ")}}if(!data.billing_phone&&billingContact.phone){data.billing_phone=billingContact.phone}if(this.args.is_3d_secure_enabled){this.log("3DS verification enabled. Verifying buyer");var self=this;try{this.payments.verifyBuyer(nonce,self.get_verification_details(billingContact,shippingContact)).then(verificationResult=>{if(verificationResult.token){self.log("3DS verification successful");data["wc-square-credit-card-buyer-verification-token"]=verificationResult.token;self.do_checkout(data)}})}catch(err){self.log("3DS verification failed");self.log(err);self.render_errors([err.message])}}else{this.do_checkout(data)}}do_checkout(data){this.process_digital_wallet_checkout(data).then(response=>{window.location=response.redirect},response=>{this.log(response,"error");this.render_errors_html(response.messages)})}get_verification_details(billingContact,shippingContact){var verification_details={intent:"CHARGE",amount:this.total_amount,currencyCode:this.payment_request.currencyCode,billingContact:{familyName:billingContact.familyName?billingContact.familyName:"",givenName:billingContact.givenName?billingContact.givenName:"",email:shippingContact.email?shippingContact.email:"",countryCode:billingContact.countryCode?billingContact.countryCode.toUpperCase():"",state:billingContact.state?billingContact.state:"",city:billingContact.city?billingContact.city:"",postalCode:billingContact.postalCode?billingContact.postalCode:"",phone:shippingContact.phone?shippingContact.phone:"",addressLines:billingContact.addressLines?billingContact.addressLines:""}};this.log(verification_details);return verification_details}recalculate_totals(data){var _this6=this;return _asyncToGenerator(function*(){return new Promise((resolve,reject)=>{return $.post(_this6.get_ajax_url("recalculate_totals"),data,response=>{if(response.success){_this6.total_amount=response.data.total.amount;return resolve(response.data)}return reject(response.data)})})})()}get_product_data(){var product_id=$(".single_add_to_cart_button").val();var attributes={};if($(".single_variation_wrap").length){product_id=$(".single_variation_wrap").find("input[name=\"product_id\"]").val();if($(".variations_form").length){$(".variations_form").find(".variations select").each((index,select)=>{var attribute_name=$(select).data("attribute_name")||$(select).attr("name");var value=$(select).val()||"";return attributes[attribute_name]=value})}}return{product_id,quantity:$(".quantity .qty").val(),attributes}}add_to_cart(){var data={security:this.args.add_to_cart_nonce};var product_data=this.get_product_data();$.extend(data,product_data);$.post(this.get_ajax_url("add_to_cart"),data,response=>{if(response.error){return window.alert(response.data)}var data=JSON.parse(response.data);this.payment_request=data.payment_request;this.args.payment_request_nonce=data.payment_request_nonce;this.args.add_to_cart_nonce=data.add_to_cart_nonce;this.args.recalculate_totals_nonce=data.recalculate_totals_nonce;this.args.process_checkout_nonce=data.process_checkout_nonce})}process_digital_wallet_checkout(data){return new Promise((resolve,reject)=>{$.post(this.get_ajax_url("process_checkout"),data,response=>{if(response.result==="success"){return resolve(response)}return reject(response)})})}get_ajax_url(request){return this.args.ajax_url.replace("%%endpoint%%","square_digital_wallet_"+request)}render_errors_html(errors_html){$(".woocommerce-error, .woocommerce-message").remove();var element=this.args.context==="product"?$(".product"):$(".shop_table.cart").closest("form");element.before(errors_html);this.unblock_ui();$("html, body").animate({scrollTop:element.offset().top-100},1000)}render_errors(errors){var error_message_html="<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>";this.render_errors_html(error_message_html)}block_ui(){$(this.buttons).block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})}unblock_ui(){$(this.buttons).unblock()}log(message){var type=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"notice";if(!this.args.logging_enabled){return}if(type==="error"){return console.error(message)}return console.log(message)}debounce(func,wait,immediate){var timeout;return function(){var context=this,args=arguments;var later=function later(){timeout=null;if(!immediate)func.apply(context,args)};var callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)func.apply(context,args)}}}window.WC_Square_Digital_Wallet_Handler=WC_Square_Digital_Wallet_Handler});
|
assets/js/frontend/wc-square-payment-gateway-apple-pay.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";(function(){var bind=function bind(fn,me){return function(){return fn.apply(me,arguments)}},extend=function extend(child,parent){for(var key in parent){if(hasProp.call(parent,key))child[key]=parent[key]}function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;child.__super__=parent.prototype;return child},hasProp={}.hasOwnProperty;jQuery(document).ready(function($){"use strict";window.SV_WC_Apple_Pay_Handler=function(){function SV_WC_Apple_Pay_Handler(args){this.get_payment_request=bind(this.get_payment_request,this);this.reset_payment_request=bind(this.reset_payment_request,this);this.attach_update_events=bind(this.attach_update_events,this);this.on_cancel_payment=bind(this.on_cancel_payment,this);this.process_authorization=bind(this.process_authorization,this);this.on_payment_authorized=bind(this.on_payment_authorized,this);this.on_shipping_method_selected=bind(this.on_shipping_method_selected,this);this.on_shipping_contact_selected=bind(this.on_shipping_contact_selected,this);this.on_payment_method_selected=bind(this.on_payment_method_selected,this);this.validate_merchant=bind(this.validate_merchant,this);this.on_validate_merchant=bind(this.on_validate_merchant,this);this.params=sv_wc_apple_pay_params;this.payment_request=args.payment_request;this.buttons=".sv-wc-apple-pay-button";if(this.is_available()){if(this.payment_request){$(this.buttons).show()}this.init();this.attach_update_events()}}SV_WC_Apple_Pay_Handler.prototype.is_available=function(){if(!window.ApplePaySession){return false}return ApplePaySession.canMakePaymentsWithActiveCard(this.params.merchant_id).then(function(_this){return function(canMakePayments){return canMakePayments}}(this))};SV_WC_Apple_Pay_Handler.prototype.init=function(){return $(document.body).on("click",".sv-wc-apple-pay-button",function(_this){return function(e){var error;e.preventDefault();_this.block_ui();try{_this.session=new ApplePaySession(1,_this.payment_request);_this.session.onvalidatemerchant=function(event){return _this.on_validate_merchant(event)};_this.session.onpaymentmethodselected=function(event){return _this.on_payment_method_selected(event)};_this.session.onshippingcontactselected=function(event){return _this.on_shipping_contact_selected(event)};_this.session.onshippingmethodselected=function(event){return _this.on_shipping_method_selected(event)};_this.session.onpaymentauthorized=function(event){return _this.on_payment_authorized(event)};_this.session.oncancel=function(event){return _this.on_cancel_payment(event)};return _this.session.begin()}catch(_error){error=_error;return _this.fail_payment(error)}}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_validate_merchant=function(event){return this.validate_merchant(event.validationURL).then(function(_this){return function(merchant_session){merchant_session=$.parseJSON(merchant_session);return _this.session.completeMerchantValidation(merchant_session)}}(this),function(_this){return function(response){_this.session.abort();return _this.fail_payment("Merchant could no be validated. "+response.message)}}(this))};SV_WC_Apple_Pay_Handler.prototype.validate_merchant=function(url){return new Promise(function(_this){return function(resolve,reject){var data;data={action:"sv_wc_apple_pay_validate_merchant",nonce:_this.params.validate_nonce,merchant_id:_this.params.merchant_id,url};return $.post(_this.params.ajax_url,data,function(response){if(response.success){return resolve(response.data)}return reject(response.data)})}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_payment_method_selected=function(event){return new Promise(function(_this){return function(resolve,reject){var data;data={action:"sv_wc_apple_pay_recalculate_totals",nonce:_this.params.recalculate_totals_nonce};return $.post(_this.params.ajax_url,data,function(response){if(response.success){data=response.data;return resolve(_this.session.completePaymentMethodSelection(data.total,data.line_items))}console.error("[Apple Pay] Error selecting a shipping contact. "+response.data.message);return reject(_this.session.completePaymentMethodSelection(_this.payment_request.total,_this.payment_request.lineItems))})}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_shipping_contact_selected=function(event){return new Promise(function(_this){return function(resolve,reject){var data;data={action:"sv_wc_apple_pay_recalculate_totals",nonce:_this.params.recalculate_totals_nonce,contact:event.shippingContact};return $.post(_this.params.ajax_url,data,function(response){if(response.success){data=response.data;return resolve(_this.session.completeShippingContactSelection(ApplePaySession.STATUS_SUCCESS,data.shipping_methods,data.total,data.line_items))}console.error("[Apple Pay] Error selecting a shipping contact. "+response.data.message);return reject(_this.session.completeShippingContactSelection(ApplePaySession.STATUS_FAILURE,[],_this.payment_request.total,_this.payment_request.lineItems))})}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_shipping_method_selected=function(event){return new Promise(function(_this){return function(resolve,reject){var data;data={action:"sv_wc_apple_pay_recalculate_totals",nonce:_this.params.recalculate_totals_nonce,method:event.shippingMethod.identifier};return $.post(_this.params.ajax_url,data,function(response){if(response.success){data=response.data;return resolve(_this.session.completeShippingMethodSelection(ApplePaySession.STATUS_SUCCESS,data.total,data.line_items))}console.error("[Apple Pay] Error selecting a shipping method. "+response.data.message);return reject(_this.session.completeShippingMethodSelection(ApplePaySession.STATUS_FAILURE,_this.payment_request.total,_this.payment_request.lineItems))})}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_payment_authorized=function(event){return this.process_authorization(event.payment).then(function(_this){return function(response){_this.set_payment_status(true);return _this.complete_purchase(response)}}(this),function(_this){return function(response){_this.set_payment_status(false);return _this.fail_payment("Payment could no be processed. "+response.message)}}(this))};SV_WC_Apple_Pay_Handler.prototype.process_authorization=function(payment){return new Promise(function(_this){return function(resolve,reject){var data;data={action:"sv_wc_apple_pay_process_payment",nonce:_this.params.process_nonce,type:_this.type,payment:JSON.stringify(payment)};return $.post(_this.params.ajax_url,data,function(response){if(response.success){return resolve(response.data)}return reject(response.data)})}}(this))};SV_WC_Apple_Pay_Handler.prototype.on_cancel_payment=function(event){return this.unblock_ui()};SV_WC_Apple_Pay_Handler.prototype.complete_purchase=function(response){return window.location=response.redirect};SV_WC_Apple_Pay_Handler.prototype.fail_payment=function(error){console.error("[Apple Pay] "+error);this.unblock_ui();return this.render_errors([this.params.generic_error])};SV_WC_Apple_Pay_Handler.prototype.set_payment_status=function(success){var status;if(success){status=ApplePaySession.STATUS_SUCCESS}else{status=ApplePaySession.STATUS_FAILURE}return this.session.completePayment(status)};SV_WC_Apple_Pay_Handler.prototype.attach_update_events=function(){};SV_WC_Apple_Pay_Handler.prototype.reset_payment_request=function(data){if(data==null){data={}}this.block_ui();return this.get_payment_request(data).then(function(_this){return function(response){$(_this.buttons).show();_this.payment_request=$.parseJSON(response);return _this.unblock_ui()}}(this),function(_this){return function(response){console.error("[Apple Pay] Could not build payment request. "+response.message);$(_this.buttons).hide();return _this.unblock_ui()}}(this))};SV_WC_Apple_Pay_Handler.prototype.get_payment_request=function(data){return new Promise(function(_this){return function(resolve,reject){var base_data;base_data={action:"sv_wc_apple_pay_get_payment_request",type:_this.type};$.extend(data,base_data);return $.post(_this.params.ajax_url,data,function(response){if(response.success){return resolve(response.data)}return reject(response.data)})}}(this))};SV_WC_Apple_Pay_Handler.prototype.render_errors=function(errors){$(".woocommerce-error, .woocommerce-message").remove();this.ui_element.prepend("<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>");this.ui_element.removeClass("processing").unblock();return $("html, body").animate({scrollTop:this.ui_element.offset().top-100},1000)};SV_WC_Apple_Pay_Handler.prototype.block_ui=function(){return this.ui_element.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})};SV_WC_Apple_Pay_Handler.prototype.unblock_ui=function(){return this.ui_element.unblock()};return SV_WC_Apple_Pay_Handler}();window.Square_Apple_Pay_Cart_Handler=function(superClass){extend(Square_Apple_Pay_Cart_Handler,superClass);function Square_Apple_Pay_Cart_Handler(args){this.attach_update_events=bind(this.attach_update_events,this);this.type="cart";this.ui_element=$("form.woocommerce-cart-form").parents("div.woocommerce");Square_Apple_Pay_Cart_Handler.__super__.constructor.call(this,args)}Square_Apple_Pay_Cart_Handler.prototype.attach_update_events=function(){return $(document.body).on("updated_cart_totals",function(_this){return function(){return _this.reset_payment_request()}}(this))};return Square_Apple_Pay_Cart_Handler}(SV_WC_Apple_Pay_Handler);window.Square_Apple_Pay_Checkout_Handler=function(superClass){extend(Square_Apple_Pay_Checkout_Handler,superClass);function Square_Apple_Pay_Checkout_Handler(args){this.attach_update_events=bind(this.attach_update_events,this);this.type="checkout";this.ui_element=$("form.woocommerce-checkout");Square_Apple_Pay_Checkout_Handler.__super__.constructor.call(this,args);this.buttons=".sv-wc-apply-pay-checkout"}Square_Apple_Pay_Checkout_Handler.prototype.attach_update_events=function(){return $(document.body).on("updated_checkout",function(_this){return function(){return _this.reset_payment_request()}}(this))};return Square_Apple_Pay_Checkout_Handler}(SV_WC_Apple_Pay_Handler);return window.Square_Apple_Pay_Product_Handler=function(superClass){extend(Square_Apple_Pay_Product_Handler,superClass);function Square_Apple_Pay_Product_Handler(args){this.type="product";this.ui_element=$("form.cart");Square_Apple_Pay_Product_Handler.__super__.constructor.call(this,args)}return Square_Apple_Pay_Product_Handler}(SV_WC_Apple_Pay_Handler)})}).call(void 0);
|
assets/js/frontend/wc-square-payment-gateway-my-payment-methods.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";(function(){var bind=function bind(fn,me){return function(){return fn.apply(me,arguments)}};jQuery(document).ready(function($){"use strict";return window.Square_Payment_Methods_Handler=function(){function Square_Payment_Methods_Handler(args){this.cancel_edit=bind(this.cancel_edit,this);this.save_method=bind(this.save_method,this);this.edit_method=bind(this.edit_method,this);this.id=args.id;this.slug=args.slug;this.i18n=args.i18n;this.ajax_url=args.ajax_url;this.ajax_nonce=args.ajax_nonce;if(!args.has_core_tokens){$(".wc-"+this.slug+"-my-payment-methods").prev(".woocommerce-Message.woocommerce-Message--info").hide()}$(".wc-"+this.slug+"-payment-method-actions .button.tip").tipTip();$(".wc-"+this.slug+"-my-payment-methods").on("click",".wc-"+this.slug+"-payment-method-actions .edit-payment-method",function(_this){return function(event){return _this.edit_method(event)}}(this));$(".wc-"+this.slug+"-my-payment-methods").on("click",".wc-"+this.slug+"-payment-method-actions .save-payment-method",function(_this){return function(event){return _this.save_method(event)}}(this));$(".wc-"+this.slug+"-my-payment-methods").on("click",".wc-"+this.slug+"-payment-method-actions .cancel-edit-payment-method",function(_this){return function(event){return _this.cancel_edit(event)}}(this));$(".wc-"+this.slug+"-my-payment-methods").on("click",".wc-"+this.slug+"-payment-method-actions .delete-payment-method",function(_this){return function(event){if($(event.currentTarget).hasClass("disabled")||!confirm(_this.i18n.delete_ays)){return event.preventDefault()}}}(this));$(".button[href*=\"add-payment-method\"]").click(function(event){if($(this).hasClass("disabled")){return event.preventDefault()}})}Square_Payment_Methods_Handler.prototype.edit_method=function(event){var button,row;event.preventDefault();button=$(event.currentTarget);row=button.parents("tr");row.find(".view").hide();row.find(".edit").show();row.addClass("editing");button.text(this.i18n.cancel_button).removeClass("edit-payment-method").addClass("cancel-edit-payment-method").removeClass("button");button.siblings(".save-payment-method").show();button.siblings(".delete-payment-method").hide();return this.enable_editing_ui()};Square_Payment_Methods_Handler.prototype.save_method=function(event){var button,data,row;event.preventDefault();button=$(event.currentTarget);row=button.parents("tr");this.block_ui();row.next(".error").remove();data={action:"wc_"+this.id+"_save_payment_method",nonce:this.ajax_nonce,token_id:row.data("token-id"),data:row.find("input[name]").serialize()};return $.post(this.ajax_url,data).done(function(_this){return function(response){if(!response.success){return _this.display_error(row,response.data)}if(response.data.is_default){row.siblings().find(".wc-"+_this.slug+"-payment-method-default .view").empty().siblings(".edit").find("input").prop("checked",false)}if(response.data.html!=null){row.replaceWith(response.data.html)}if(response.data.nonce!=null){_this.ajax_nonce=response.data.nonce}return _this.disable_editing_ui()}}(this)).fail(function(_this){return function(jqXHR,textStatus,error){return _this.display_error(row,error)}}(this)).always(function(_this){return function(){return _this.unblock_ui()}}(this))};Square_Payment_Methods_Handler.prototype.cancel_edit=function(event){var button,row;event.preventDefault();button=$(event.currentTarget);row=button.parents("tr");row.find(".view").show();row.find(".edit").hide();row.removeClass("editing");button.removeClass("cancel-edit-payment-method").addClass("edit-payment-method").text(this.i18n.edit_button).addClass("button");button.siblings(".save-payment-method").hide();button.siblings(".delete-payment-method").show();return this.disable_editing_ui()};Square_Payment_Methods_Handler.prototype.enable_editing_ui=function(){$(".wc-"+this.slug+"-my-payment-methods").addClass("editing");return $(".button[href*=\"add-payment-method\"]").addClass("disabled")};Square_Payment_Methods_Handler.prototype.disable_editing_ui=function(){$(".wc-"+this.slug+"-my-payment-methods").removeClass("editing");return $(".button[href*=\"add-payment-method\"]").removeClass("disabled")};Square_Payment_Methods_Handler.prototype.block_ui=function(){return $(".wc-"+this.slug+"-my-payment-methods").parent("div").block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})};Square_Payment_Methods_Handler.prototype.unblock_ui=function(){return $(".wc-"+this.slug+"-my-payment-methods").parent("div").unblock()};Square_Payment_Methods_Handler.prototype.display_error=function(row,error,message){var columns;if(message==null){message=""}console.error(error);if(!message){message=this.i18n.save_error}columns=$(".wc-"+this.slug+"-my-payment-methods thead tr th").size();return $("<tr class=\"error\"><td colspan=\""+columns+"\">"+message+"</td></tr>").insertAfter(row).find("td").delay(8000).slideUp(200)};return Square_Payment_Methods_Handler}()})}).call(void 0);
|
assets/js/frontend/wc-square-payment-gateway-payment-form.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";(function(){var indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i<l;i++){if(i in this&&this[i]===item)return i}return-1};jQuery(document).ready(function($){"use strict";return window.Square_Payment_Form_Handler=function(){function Square_Payment_Form_Handler(args){this.id=args.id;this.id_dasherized=args.id_dasherized;this.plugin_id=args.plugin_id;this.type=args.type;this.csc_required=args.csc_required;this.csc_required_for_tokens=args.csc_required_for_tokens;this.enabled_card_types=args.enabled_card_types;if($("form.checkout").length){this.form=$("form.checkout");this.handle_checkout_page()}else if($("form#order_review").length){this.form=$("form#order_review");this.handle_pay_page()}else if($("form#add_payment_method").length){this.form=$("form#add_payment_method");this.handle_add_payment_method_page()}else{console.log("No payment form found!");return}this.params=window.sv_wc_payment_gateway_payment_form_params;if(this.type==="echeck"){this.form.on("click",".js-sv-wc-payment-gateway-echeck-form-check-hint, .js-sv-wc-payment-gateway-echeck-form-sample-check",function(_this){return function(){return _this.handle_sample_check_hint()}}(this))}$(document).trigger("sv_wc_payment_form_handler_init",{id:this.id,instance:this})}Square_Payment_Form_Handler.prototype.handle_checkout_page=function(){if(this.type==="credit-card"){$(document.body).on("updated_checkout",function(_this){return function(){return _this.format_credit_card_inputs()}}(this))}$(document.body).on("updated_checkout",function(_this){return function(){return _this.set_payment_fields()}}(this));$(document.body).on("updated_checkout",function(_this){return function(){return _this.handle_saved_payment_methods()}}(this));return this.form.on("checkout_place_order_"+this.id,function(_this){return function(){return _this.validate_payment_data()}}(this))};Square_Payment_Form_Handler.prototype.handle_pay_page=function(){this.set_payment_fields();if(this.type==="credit-card"){this.format_credit_card_inputs()}this.handle_saved_payment_methods();return this.form.submit(function(_this){return function(){if($("#order_review input[name=payment_method]:checked").val()===_this.id){return _this.validate_payment_data()}}}(this))};Square_Payment_Form_Handler.prototype.handle_add_payment_method_page=function(){this.set_payment_fields();if(this.type==="credit-card"){this.format_credit_card_inputs()}return this.form.submit(function(_this){return function(){if($("#add_payment_method input[name=payment_method]:checked").val()===_this.id){return _this.validate_payment_data()}}}(this))};Square_Payment_Form_Handler.prototype.set_payment_fields=function(){return this.payment_fields=$(".payment_method_"+this.id)};Square_Payment_Form_Handler.prototype.validate_payment_data=function(){var handler,valid;if(this.form.is(".processing")){return false}this.saved_payment_method_selected=this.payment_fields.find(".js-sv-wc-payment-gateway-payment-token:checked").val();valid=this.type==="credit-card"?this.validate_card_data():this.validate_account_data();handler=$(document.body).triggerHandler("sv_wc_payment_form_valid_payment_data",{payment_form:this,passed_validation:valid})!==false;return valid&&handler};Square_Payment_Form_Handler.prototype.format_credit_card_inputs=function(){$(".js-sv-wc-payment-gateway-credit-card-form-account-number").payment("formatCardNumber").change();$(".js-sv-wc-payment-gateway-credit-card-form-expiry").payment("formatCardExpiry").change();$(".js-sv-wc-payment-gateway-credit-card-form-csc").payment("formatCardCVC").change();return $(".js-sv-wc-payment-gateway-credit-card-form-input").on("change paste keyup",function(_this){return function(){return _this.do_inline_credit_card_validation()}}(this))};Square_Payment_Form_Handler.prototype.do_inline_credit_card_validation=function(){var $card_number,$card_type,$csc,$expiry;$card_number=$(".js-sv-wc-payment-gateway-credit-card-form-account-number");$expiry=$(".js-sv-wc-payment-gateway-credit-card-form-expiry");$csc=$(".js-sv-wc-payment-gateway-credit-card-form-csc");$card_type=$.payment.cardType($card_number.val());if(indexOf.call(this.enabled_card_types,$card_type)<0){$card_number.addClass("invalid-card-type")}else{$card_number.removeClass("invalid-card-type")}if($.payment.validateCardExpiry($expiry.payment("cardExpiryVal"))){$expiry.addClass("identified")}else{$expiry.removeClass("identified")}if($.payment.validateCardCVC($csc.val())){return $csc.addClass("identified")}return $csc.removeClass("identified")};Square_Payment_Form_Handler.prototype.validate_card_data=function(){var account_number,csc,errors,expiry;errors=[];csc=this.payment_fields.find(".js-sv-wc-payment-gateway-credit-card-form-csc").val();if(csc!=null){if(csc){if(/\D/.test(csc)){errors.push(this.params.cvv_digits_invalid)}if(csc.length<3||csc.length>4){errors.push(this.params.cvv_length_invalid)}}else if(this.csc_required){if(!this.saved_payment_method_selected||this.csc_required_for_tokens){errors.push(this.params.cvv_missing)}}}if(!this.saved_payment_method_selected){account_number=this.payment_fields.find(".js-sv-wc-payment-gateway-credit-card-form-account-number").val();expiry=$.payment.cardExpiryVal(this.payment_fields.find(".js-sv-wc-payment-gateway-credit-card-form-expiry").val());account_number=account_number.replace(/-|\s/g,"");if(!account_number){errors.push(this.params.card_number_missing)}else{if(account_number.length<12||account_number.length>19){errors.push(this.params.card_number_length_invalid)}if(/\D/.test(account_number)){errors.push(this.params.card_number_digits_invalid)}if(!$.payment.validateCardNumber(account_number)){errors.push(this.params.card_number_invalid)}}if(!$.payment.validateCardExpiry(expiry)){errors.push(this.params.card_exp_date_invalid)}}if(errors.length>0){this.render_errors(errors);return false}this.payment_fields.find(".js-sv-wc-payment-gateway-credit-card-form-account-number").val(account_number);return true};Square_Payment_Form_Handler.prototype.validate_account_data=function(){var account_number,errors,routing_number;if(this.saved_payment_method_selected){return true}errors=[];routing_number=this.payment_fields.find(".js-sv-wc-payment-gateway-echeck-form-routing-number").val();account_number=this.payment_fields.find(".js-sv-wc-payment-gateway-echeck-form-account-number").val();if(!routing_number){errors.push(this.params.routing_number_missing)}else{if(routing_number.length!==9){errors.push(this.params.routing_number_length_invalid)}if(/\D/.test(routing_number)){errors.push(this.params.routing_number_digits_invalid)}}if(!account_number){errors.push(this.params.account_number_missing)}else{if(account_number.length<3||account_number.length>17){errors.push(this.params.account_number_length_invalid)}if(/\D/.test(account_number)){errors.push(this.params.account_number_invalid)}}if(errors.length>0){this.render_errors(errors);return false}this.payment_fields.find(".js-sv-wc-payment-gateway-echeck-form-account-number").val(account_number);return true};Square_Payment_Form_Handler.prototype.render_errors=function(errors){$(".woocommerce-error, .woocommerce-message").remove();this.form.prepend("<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>");this.form.removeClass("processing").unblock();this.form.find(".input-text, select").blur();return $("html, body").animate({scrollTop:this.form.offset().top-100},1000)};Square_Payment_Form_Handler.prototype.handle_saved_payment_methods=function(){var $csc_field,$new_payment_method_selection,csc_required,csc_required_for_tokens,id_dasherized;id_dasherized=this.id_dasherized;csc_required=this.csc_required;csc_required_for_tokens=this.csc_required_for_tokens;$new_payment_method_selection=$("div.js-wc-"+id_dasherized+"-new-payment-method-form");$csc_field=$new_payment_method_selection.find(".js-sv-wc-payment-gateway-credit-card-form-csc").closest(".form-row");$("input.js-wc-"+this.id_dasherized+"-payment-token").change(function(){var tokenized_payment_method_selected;tokenized_payment_method_selected=$("input.js-wc-"+id_dasherized+"-payment-token:checked").val();if(tokenized_payment_method_selected){$new_payment_method_selection.slideUp(200);if(csc_required_for_tokens){$csc_field.removeClass("form-row-last").addClass("form-row-first");return $new_payment_method_selection.after($csc_field)}}else{$new_payment_method_selection.slideDown(200);if(csc_required_for_tokens){$csc_field.removeClass("form-row-first").addClass("form-row-last");return $new_payment_method_selection.find(".js-sv-wc-payment-gateway-credit-card-form-expiry").closest(".form-row").after($csc_field)}}}).change();$("input#createaccount").change(function(){var $parent_row;$parent_row=$("input.js-wc-"+id_dasherized+"-tokenize-payment-method").closest("p.form-row");if($(this).is(":checked")){$parent_row.slideDown();return $parent_row.next().show()}$parent_row.hide();return $parent_row.next().hide()});if(!$("input#createaccount").is(":checked")){return $("input#createaccount").change()}};Square_Payment_Form_Handler.prototype.handle_sample_check_hint=function(){var $sample_check;$sample_check=this.payment_fields.find(".js-sv-wc-payment-gateway-echeck-form-sample-check");if($sample_check.is(":visible")){return $sample_check.slideUp()}return $sample_check.slideDown()};Square_Payment_Form_Handler.prototype.block_ui=function(){return this.form.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})};Square_Payment_Form_Handler.prototype.unblock_ui=function(){return this.form.unblock()};return Square_Payment_Form_Handler}()})}).call(void 0);
|
assets/js/frontend/wc-square.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";function _toConsumableArray(arr){return _arrayWithoutHoles(arr)||_iterableToArray(arr)||_unsupportedIterableToArray(arr)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _arrayWithoutHoles(arr){if(Array.isArray(arr))return _arrayLikeToArray(arr)}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_unsupportedIterableToArray(arr,i)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i]}return arr2}function _iterableToArrayLimit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor}jQuery(document).ready(function($){var WC_Square_Payment_Form_Handler=function(){function WC_Square_Payment_Form_Handler(args){var _this=this;_classCallCheck(this,WC_Square_Payment_Form_Handler);this.id=args.id;this.id_dasherized=args.id_dasherized;this.csc_required=args.csc_required;this.enabled_card_types=args.enabled_card_types;this.square_card_types=args.square_card_types;this.ajax_log_nonce=args.ajax_log_nonce;this.ajax_url=args.ajax_url;this.application_id=args.application_id;this.currency_code=args.currency_code;this.general_error=args.general_error;this.input_styles=args.input_styles;this.is_3ds_enabled=args.is_3d_secure_enabled;this.is_add_payment_method_page=args.is_add_payment_method_page;this.is_checkout_registration_enabled=args.is_checkout_registration_enabled;this.is_user_logged_in=args.is_user_logged_in;this.location_id=args.location_id;this.logging_enabled=args.logging_enabled;this.ajax_wc_checkout_validate_nonce=args.ajax_wc_checkout_validate_nonce;this.is_manual_order_payment=args.is_manual_order_payment;this.current_postal_code_value="";if($("form.checkout").length){this.form=$("form.checkout");this.handle_checkout_page()}else if($("form#order_review").length){this.form=$("form#order_review");this.handle_pay_page()}else if($("form#add_payment_method").length){this.form=$("form#add_payment_method");this.handle_add_payment_method_page()}else{this.log("No payment form found!");return}this.params=window.sv_wc_payment_gateway_payment_form_params;$(document.body).on("checkout_error",function(){$("input[name=wc-square-credit-card-payment-nonce]").val("");$("input[name=wc-square-credit-card-buyer-verification-token]").val("")});$(document.body).on("click","#payment_method_".concat(this.id),function(){if(_this.payment_form){_this.log("Recalculating payment form size");_this.payment_form.recalculateSize()}})}_createClass(WC_Square_Payment_Form_Handler,[{key:"handle_checkout_page",value:function handle_checkout_page(){var _this2=this;$(document.body).on("updated_checkout",function(){return _this2.set_payment_fields()});$(document.body).on("updated_checkout",function(){return _this2.handle_saved_payment_methods()});this.form.on("checkout_place_order_".concat(this.id),function(){return _this2.validate_payment_data()})}},{key:"handle_saved_payment_methods",value:function handle_saved_payment_methods(){var id_dasherized=this.id_dasherized;var form_handler=this;var $new_payment_method_selection=$("div.js-wc-".concat(id_dasherized,"-new-payment-method-form"));$("input.js-wc-".concat(this.id_dasherized,"-payment-token")).on("change",function(){var tokenized_payment_method_selected=$("input.js-wc-".concat(id_dasherized,"-payment-token:checked")).val();if(tokenized_payment_method_selected){$new_payment_method_selection.slideUp(200)}else{$new_payment_method_selection.slideDown(200)}}).trigger("change");$("input#createaccount").on("change",function(e){if($(e.target).is(":checked")){form_handler.show_save_payment_checkbox(id_dasherized)}else{form_handler.hide_save_payment_checkbox(id_dasherized)}});if(!$("input#createaccount").is(":checked")){$("input#createaccount").trigger("change")}if(!this.is_user_logged_in&&!this.is_checkout_registration_enabled){this.hide_save_payment_checkbox(id_dasherized)}}},{key:"handle_pay_page",value:function handle_pay_page(){this.set_payment_fields();this.handle_saved_payment_methods();var self=this;this.form.on("submit",function(){if($("#order_review input[name=payment_method]:checked").val()===self.id){return self.validate_payment_data()}})}},{key:"handle_add_payment_method_page",value:function handle_add_payment_method_page(){this.set_payment_fields();var self=this;this.form.on("submit",function(){if($("#add_payment_method input[name=payment_method]:checked").val()===self.id){return self.validate_payment_data()}})}},{key:"set_payment_fields",value:function set_payment_fields(){if(!$("#wc-".concat(this.id_dasherized,"-account-number-hosted")).length){return}if($("#wc-".concat(this.id_dasherized,"-account-number-hosted")).is("iframe")){this.log("Re-adding payment form");for(var _i=0,_Object$entries=Object.entries(this.form_fields);_i<_Object$entries.length;_i++){var _Object$entries$_i=_slicedToArray(_Object$entries[_i],2),_=_Object$entries$_i[0],field=_Object$entries$_i[1];$(field.attr("id")).replaceWith(field)}this.handle_form_loaded()}else{if(this.payment_form){this.log("Destroying payment form");this.payment_form.destroy();this.payment_form=null}this.log("Building payment form");this.payment_form=new SqPaymentForm(this.get_form_params());this.payment_form.build()}}},{key:"get_form_params",value:function get_form_params(){var _this3=this;this.form_fields={card_number:$("#wc-".concat(this.id_dasherized,"-account-number-hosted")),expiration:$("#wc-".concat(this.id_dasherized,"-expiry-hosted")),csc:$("#wc-".concat(this.id_dasherized,"-csc-hosted")),postal_code:$("#wc-".concat(this.id_dasherized,"-postal-code-hosted"))};return{applicationId:this.application_id,locationId:this.location_id,cardNumber:{elementId:this.form_fields.card_number.attr("id"),placeholder:this.form_fields.card_number.data("placeholder")},expirationDate:{elementId:this.form_fields.expiration.attr("id"),placeholder:this.form_fields.expiration.data("placeholder")},cvv:{elementId:this.form_fields.csc.attr("id"),placeholder:this.form_fields.csc.data("placeholder")},postalCode:{elementId:this.form_fields.postal_code.attr("id"),placeholder:this.form_fields.postal_code.data("placeholder")},inputClass:"wc-".concat(this.id_dasherized,"-payment-field"),inputStyles:this.input_styles,callbacks:{inputEventReceived:function inputEventReceived(e){return _this3.handle_input_event(e)},cardNonceResponseReceived:function cardNonceResponseReceived(errors,nonce,cardData){return _this3.handle_card_nonce_response(errors,nonce,cardData)},unsupportedBrowserDetected:function unsupportedBrowserDetected(){return _this3.handle_unsupported_browser()},paymentFormLoaded:function paymentFormLoaded(){return _this3.handle_form_loaded()}}}}},{key:"handle_form_loaded",value:function handle_form_loaded(){this.log("Payment form loaded");this.payment_form.setPostalCode($("#billing_postcode").val());if($("form.checkout").length||$("#billing_postcode").val()){$(".wc-square-credit-card-card-postal-code-parent").addClass("hidden")}}},{key:"handle_input_event",value:function handle_input_event(e){var $input=$("#"+e.elementId);if(e.eventType==="cardBrandChanged"){this.handle_card_brand_change(e.cardBrand,$input)}if(e.field==="postalCode"){this.current_postal_code_value=e.postalCodeValue;if(e.eventType==="focusClassRemoved"){this.payment_form.setPostalCode(this.current_postal_code_value.trim())}}}},{key:"handle_card_brand_change",value:function handle_card_brand_change(brand,$input){this.log("Card brand changed to ".concat(brand));$input.attr("class",function(i,c){return c.replace(/(^|\s)card-type-\S+/g,"")});var card_class="plain";if(null===brand||"unknown"===brand){brand=""}if(null!==this.square_card_types[brand]){brand=this.square_card_types[brand]}if(brand&&!this.enabled_card_types.includes(brand)){card_class="invalid"}else{card_class=brand}$("input[name=wc-".concat(this.id_dasherized,"-card-type]")).val(brand);$input.addClass("card-type-".concat(card_class))}},{key:"validate_payment_data",value:function validate_payment_data(){if(this.form.is(".processing")){return false}if(this.has_nonce()){this.log("Payment nonce present, placing order");return true}var tokenized_card_id=this.get_tokenized_payment_method_id();if(tokenized_card_id){if(!this.is_3ds_enabled){return true}if(this.has_verification_token()){this.log("Tokenized payment verification token present, placing order");return true}this.log("Requesting verification token for tokenized payment");this.block_ui();this.payment_form.verifyBuyer(tokenized_card_id,this.get_verification_details(),this.handle_verify_buyer_response.bind(this));return false}this.log("Requesting payment nonce");this.block_ui();this.payment_form.requestCardNonce();return false}},{key:"get_tokenized_payment_method_id",value:function get_tokenized_payment_method_id(){return $(".payment_method_".concat(this.id)).find(".js-wc-square-credit-card-payment-token:checked").val()}},{key:"handle_card_nonce_response",value:function handle_card_nonce_response(errors,nonce,cardData){if(errors){return this.handle_errors(errors)}if(!nonce){var message="Nonce is missing from the Square response";this.log(message,"error");this.log_data(message,"response");return this.handle_errors()}this.log("Card data received");this.log(cardData);this.log_data(cardData,"response");if(cardData.last_4){$("input[name=wc-".concat(this.id_dasherized,"-last-four]")).val(cardData.last_4)}if(cardData.exp_month){$("input[name=wc-".concat(this.id_dasherized,"-exp-month]")).val(cardData.exp_month)}if(cardData.exp_year){$("input[name=wc-".concat(this.id_dasherized,"-exp-year]")).val(cardData.exp_year)}if(cardData.billing_postal_code){$("input[name=wc-".concat(this.id_dasherized,"-payment-postcode]")).val(cardData.billing_postal_code)}$("input[name=wc-".concat(this.id_dasherized,"-payment-nonce]")).val(nonce);if(this.is_3ds_enabled){this.log("Verifying buyer");this.payment_form.verifyBuyer(nonce,this.get_verification_details(),this.handle_verify_buyer_response.bind(this));return}this.form.trigger("submit")}},{key:"handle_verify_buyer_response",value:function handle_verify_buyer_response(errors,verification_result){if(errors){$(errors).each(function(index,error){if(!error.field){error.field="none"}});return this.handle_errors(errors)}if(!verification_result||!verification_result.token){var message="Verification token is missing from the Square response";this.log(message,"error");this.log_data(message,"response");return this.handle_errors()}this.log("Verification result received");this.log(verification_result);$("input[name=wc-".concat(this.id_dasherized,"-buyer-verification-token]")).val(verification_result.token);this.form.trigger("submit")}},{key:"get_verification_details",value:function get_verification_details(){var verification_details={billingContact:{familyName:$("#billing_last_name").val()||"",givenName:$("#billing_first_name").val()||"",email:$("#billing_email").val()||"",country:$("#billing_country").val()||"",region:$("#billing_state").val()||"",city:$("#billing_city").val()||"",postalCode:$("#billing_postcode").val()||"",phone:$("#billing_phone").val()||"",addressLines:[$("#billing_address_1").val()||"",$("#billing_address_2").val()||""]},intent:this.get_intent()};if("CHARGE"===verification_details.intent){verification_details.amount=this.get_amount();verification_details.currencyCode=this.currency_code}this.log(verification_details);return verification_details}},{key:"get_intent",value:function get_intent(){var $save_method_input=$("#wc-square-credit-card-tokenize-payment-method");var save_payment_method;if($save_method_input.is("input:checkbox")){save_payment_method=$save_method_input.is(":checked")}else{save_payment_method="true"===$save_method_input.val()}if(!this.get_tokenized_payment_method_id()&&save_payment_method){return"STORE"}return"CHARGE"}},{key:"get_amount",value:function get_amount(){return $("input[name=wc-".concat(this.id_dasherized,"-amount]")).val()}},{key:"handle_unsupported_browser",value:function handle_unsupported_browser(){}},{key:"handle_errors",value:function handle_errors(){var _this4=this;var errors=arguments.length>0&&arguments[0]!==undefined?arguments[0]:null;this.log("Error getting payment data","error");$("input[name=wc-square-credit-card-payment-nonce]").val("");$("input[name=wc-square-credit-card-buyer-verification-token]").val("");var messages=[];if(errors){var field_order=["none","cardNumber","expirationDate","cvv","postalCode"];if(errors.length>=1){errors.sort(function(a,b){return field_order.indexOf(a.field)-field_order.indexOf(b.field)})}$(errors).each(function(index,error){if("UNSUPPORTED_CARD_BRAND"===error.type||"VALIDATION_ERROR"===error.type){return messages.push(error.message.replace(/CVV/,"CSC"))}return _this4.log_data(errors,"response")})}if(messages.length===0){messages.push(this.general_error)}if(!this.is_add_payment_method_page&&!this.is_manual_order_payment){this.render_checkout_errors(messages)}else{this.render_errors(messages)}this.unblock_ui()}},{key:"render_errors",value:function render_errors(errors){$(".woocommerce-error, .woocommerce-message").remove();this.form.prepend("<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>");this.form.removeClass("processing").unblock();this.form.find(".input-text, select").trigger("blur");$("html, body").animate({scrollTop:this.form.offset().top-100},1000)}},{key:"block_ui",value:function block_ui(){this.form.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})}},{key:"unblock_ui",value:function unblock_ui(){return this.form.unblock()}},{key:"hide_save_payment_checkbox",value:function hide_save_payment_checkbox(id_dasherized){var $parent_row=$("input.js-wc-".concat(id_dasherized,"-tokenize-payment-method")).closest("p.form-row");$parent_row.hide();$parent_row.next().hide()}},{key:"show_save_payment_checkbox",value:function show_save_payment_checkbox(id_dasherized){var $parent_row=$("input.js-wc-".concat(id_dasherized,"-tokenize-payment-method")).closest("p.form-row");$parent_row.slideDown();$parent_row.next().show()}},{key:"has_nonce",value:function has_nonce(){return $("input[name=wc-".concat(this.id_dasherized,"-payment-nonce]")).val()}},{key:"has_verification_token",value:function has_verification_token(){return $("input[name=wc-".concat(this.id_dasherized,"-buyer-verification-token]")).val()}},{key:"log_data",value:function log_data(data,type){if(!this.logging_enabled){return}var ajax_data={action:"wc_"+this.id+"_log_js_data",security:this.ajax_log_nonce,type:type,data:data};$.ajax({url:this.ajax_url,data:ajax_data})}},{key:"log",value:function log(message){var type=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"notice";if(!this.logging_enabled){return}if("error"===type){console.error("Square Error: "+message)}else{console.log("Square: "+message)}}},{key:"render_checkout_errors",value:function render_checkout_errors(square_errors){var _this5=this;var ajax_url=wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%",this.id+"_checkout_handler");var square_handler=this;var form_data=this.form.serializeArray();form_data.push({name:"wc_"+this.id+"_checkout_validate_nonce",value:this.ajax_wc_checkout_validate_nonce});return $.ajax({url:ajax_url,method:"post",cache:false,data:form_data,complete:function complete(response){var result=response.responseJSON;if(result.hasOwnProperty("result")&&"failure"===result.result){$(result.messages).map(function(message){var errors=[];$(message).children("li").each(function(){errors.push($(_this5).text().trim())});return square_errors.unshift.apply(square_errors,errors)})}else if(result.hasOwnProperty("success")&&!result.success){square_errors.unshift.apply(square_errors,_toConsumableArray(result.data.messages))}square_handler.render_errors(square_errors)}})}}]);return WC_Square_Payment_Form_Handler}();window.WC_Square_Payment_Form_Handler=WC_Square_Payment_Form_Handler});
|
1 |
+
"use strict";jQuery(document).ready($=>{class WC_Square_Payment_Form_Handler{constructor(args){this.id=args.id;this.id_dasherized=args.id_dasherized;this.csc_required=args.csc_required;this.enabled_card_types=args.enabled_card_types;this.square_card_types=args.square_card_types;this.ajax_log_nonce=args.ajax_log_nonce;this.ajax_url=args.ajax_url;this.application_id=args.application_id;this.currency_code=args.currency_code;this.general_error=args.general_error;this.input_styles=args.input_styles;this.is_3ds_enabled=args.is_3d_secure_enabled;this.is_add_payment_method_page=args.is_add_payment_method_page;this.is_checkout_registration_enabled=args.is_checkout_registration_enabled;this.is_user_logged_in=args.is_user_logged_in;this.location_id=args.location_id;this.logging_enabled=args.logging_enabled;this.ajax_wc_checkout_validate_nonce=args.ajax_wc_checkout_validate_nonce;this.is_manual_order_payment=args.is_manual_order_payment;this.current_postal_code_value="";if($("form.checkout").length){this.form=$("form.checkout");this.handle_checkout_page()}else if($("form#order_review").length){this.form=$("form#order_review");this.handle_pay_page()}else if($("form#add_payment_method").length){this.form=$("form#add_payment_method");this.handle_add_payment_method_page()}else{this.log("No payment form found!");return}this.params=window.sv_wc_payment_gateway_payment_form_params;$(document.body).on("checkout_error",()=>{$("input[name=wc-square-credit-card-payment-nonce]").val("");$("input[name=wc-square-credit-card-buyer-verification-token]").val("")});$(document.body).on("change","#payment_method_".concat(this.id),()=>{if(this.payment_form){this.log("Recalculating payment form size");this.payment_form.recalculateSize()}})}handle_checkout_page(){$(document.body).on("updated_checkout",()=>this.set_payment_fields());$(document.body).on("updated_checkout",()=>this.handle_saved_payment_methods());this.form.on("checkout_place_order_".concat(this.id),()=>this.validate_payment_data())}handle_saved_payment_methods(){var id_dasherized=this.id_dasherized;var form_handler=this;var $new_payment_method_selection=$("div.js-wc-".concat(id_dasherized,"-new-payment-method-form"));$("input.js-wc-".concat(this.id_dasherized,"-payment-token")).on("change",()=>{var tokenized_payment_method_selected=$("input.js-wc-".concat(id_dasherized,"-payment-token:checked")).val();if(tokenized_payment_method_selected){$new_payment_method_selection.slideUp(200)}else{$new_payment_method_selection.slideDown(200)}}).trigger("change");$("input#createaccount").on("change",e=>{if($(e.target).is(":checked")){form_handler.show_save_payment_checkbox(id_dasherized)}else{form_handler.hide_save_payment_checkbox(id_dasherized)}});if(!$("input#createaccount").is(":checked")){$("input#createaccount").trigger("change")}if(!this.is_user_logged_in&&!this.is_checkout_registration_enabled){this.hide_save_payment_checkbox(id_dasherized)}}handle_pay_page(){this.set_payment_fields();this.handle_saved_payment_methods();var self=this;this.form.on("submit",function(){if($("#order_review input[name=payment_method]:checked").val()===self.id){return self.validate_payment_data()}})}handle_add_payment_method_page(){this.set_payment_fields();var self=this;this.form.on("submit",function(){if($("#add_payment_method input[name=payment_method]:checked").val()===self.id){return self.validate_payment_data()}})}set_payment_fields(){if(this.payment_form){this.log("Destroying payment form");this.payment_form.destroy().then(()=>{this.log("Re-building payment form");this.initializeCard(this.payments)});return}this.log("Building payment form");var{applicationId,locationId}=this.get_form_params();this.payments=window.Square.payments(applicationId,locationId);this.initializeCard(this.payments)}initializeCard(payments){var defaultPostalCode=$("#billing_postcode").val();defaultPostalCode=defaultPostalCode||"";payments.card({postalCode:defaultPostalCode}).then(card=>{card.attach("#wc-square-credit-card-container");this.payment_form=card;this.log("Payment form loaded")})}get_form_params(){return{applicationId:this.application_id,locationId:this.location_id}}validate_payment_data(){if(this.form.is(".processing")){return false}if(this.has_nonce()){this.log("Payment nonce present, placing order");return true}var tokenized_card_id=this.get_tokenized_payment_method_id();if(tokenized_card_id){if(!this.is_3ds_enabled){return true}if(this.has_verification_token()){this.log("Tokenized payment verification token present, placing order");return true}this.log("Requesting verification token for tokenized payment");this.block_ui();this.payments.verifyBuyer(tokenized_card_id,this.get_verification_details()).then(verificationResult=>{this.handle_verify_buyer_response(false,verificationResult)});return false}this.log("Requesting payment nonce");this.block_ui();this.handleSubmission();return false}handleSubmission(){var tokenPromise=this.payment_form.tokenize();tokenPromise.then(tokenResult=>{var{token,details,status}=tokenResult;if(status==="OK"){this.handle_card_nonce_response(token,details)}else{if(tokenResult.errors){this.handle_errors(tokenResult.errors)}}})}get_tokenized_payment_method_id(){return $(".payment_method_".concat(this.id)).find(".js-wc-square-credit-card-payment-token:checked").val()}handle_card_nonce_response(nonce,details){var{card:cardData,billing}=details;if(!nonce){var message="Nonce is missing from the Square response";this.log(message,"error");this.log_data(message,"response");return this.handle_errors()}this.log("Card data received");this.log(cardData);this.log_data(cardData,"response");if(cardData.last4){$("input[name=wc-".concat(this.id_dasherized,"-last-four]")).val(cardData.last4)}if(cardData.expMonth){$("input[name=wc-".concat(this.id_dasherized,"-exp-month]")).val(cardData.expMonth)}if(cardData.expYear){$("input[name=wc-".concat(this.id_dasherized,"-exp-year]")).val(cardData.expYear)}if(billing.postalCode){$("input[name=wc-".concat(this.id_dasherized,"-payment-postcode]")).val(billing.postalCode)}if(cardData.brand){$("input[name=wc-".concat(this.id_dasherized,"-card-type]")).val(cardData.brand)}$("input[name=wc-".concat(this.id_dasherized,"-payment-nonce]")).val(nonce);if(this.is_3ds_enabled){this.log("Verifying buyer");this.payments.verifyBuyer(nonce,this.get_verification_details()).then(verificationResult=>{this.handle_verify_buyer_response(false,verificationResult)});return}this.form.trigger("submit")}handle_verify_buyer_response(errors,verification_result){if(errors){$(errors).each((index,error)=>{if(!error.field){error.field="none"}});return this.handle_errors(errors)}if(!verification_result||!verification_result.token){var message="Verification token is missing from the Square response";this.log(message,"error");this.log_data(message,"response");return this.handle_errors()}this.log("Verification result received");this.log(verification_result);$("input[name=wc-".concat(this.id_dasherized,"-buyer-verification-token]")).val(verification_result.token);this.form.trigger("submit")}get_verification_details(){var verification_details={billingContact:{familyName:$("#billing_last_name").val()||"",givenName:$("#billing_first_name").val()||"",email:$("#billing_email").val()||"",country:$("#billing_country").val()||"",region:$("#billing_state").val()||"",city:$("#billing_city").val()||"",postalCode:$("#billing_postcode").val()||"",phone:$("#billing_phone").val()||"",addressLines:[$("#billing_address_1").val()||"",$("#billing_address_2").val()||""]},intent:this.get_intent()};if("CHARGE"===verification_details.intent){verification_details.amount=this.get_amount();verification_details.currencyCode=this.currency_code}this.log(verification_details);return verification_details}get_intent(){var $save_method_input=$("#wc-square-credit-card-tokenize-payment-method");var save_payment_method;if($save_method_input.is("input:checkbox")){save_payment_method=$save_method_input.is(":checked")}else{save_payment_method="true"===$save_method_input.val()}if(!this.get_tokenized_payment_method_id()&&save_payment_method){return"STORE"}return"CHARGE"}get_amount(){return $("input[name=wc-".concat(this.id_dasherized,"-amount]")).val()}handle_errors(){var errors=arguments.length>0&&arguments[0]!==undefined?arguments[0]:null;this.log("Error getting payment data","error");$("input[name=wc-square-credit-card-payment-nonce]").val("");$("input[name=wc-square-credit-card-buyer-verification-token]").val("");var messages=[];if(errors){var field_order=["none","cardNumber","expirationDate","cvv","postalCode"];if(errors.length>=1){errors.sort((a,b)=>{return field_order.indexOf(a.field)-field_order.indexOf(b.field)})}$(errors).each((index,error)=>{if("UNSUPPORTED_CARD_BRAND"===error.type||"VALIDATION_ERROR"===error.type){return messages.push(error.message)}return this.log_data(errors,"response")})}if(messages.length===0){messages.push(this.general_error)}if(!this.is_add_payment_method_page&&!this.is_manual_order_payment){this.render_checkout_errors(messages)}else{this.render_errors(messages)}this.unblock_ui()}render_errors(errors){$(".woocommerce-error, .woocommerce-message").remove();this.form.prepend("<ul class=\"woocommerce-error\"><li>"+errors.join("</li><li>")+"</li></ul>");this.form.removeClass("processing").unblock();this.form.find(".input-text, select").trigger("blur");$("html, body").animate({scrollTop:this.form.offset().top-100},1000)}block_ui(){this.form.block({message:null,overlayCSS:{background:"#fff",opacity:0.6}})}unblock_ui(){return this.form.unblock()}hide_save_payment_checkbox(id_dasherized){var $parent_row=$("input.js-wc-".concat(id_dasherized,"-tokenize-payment-method")).closest("p.form-row");$parent_row.hide();$parent_row.next().hide()}show_save_payment_checkbox(id_dasherized){var $parent_row=$("input.js-wc-".concat(id_dasherized,"-tokenize-payment-method")).closest("p.form-row");$parent_row.slideDown();$parent_row.next().show()}has_nonce(){return $("input[name=wc-".concat(this.id_dasherized,"-payment-nonce]")).val()}has_verification_token(){return $("input[name=wc-".concat(this.id_dasherized,"-buyer-verification-token]")).val()}log_data(data,type){if(!this.logging_enabled){return}var ajax_data={action:"wc_"+this.id+"_log_js_data",security:this.ajax_log_nonce,type,data};$.ajax({url:this.ajax_url,data:ajax_data})}log(message){var type=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"notice";if(!this.logging_enabled){return}if("error"===type){console.error("Square Error: "+message)}else{console.log("Square: "+message)}}render_checkout_errors(square_errors){var ajax_url=wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%",this.id+"_checkout_handler");var square_handler=this;var form_data=this.form.serializeArray();form_data.push({name:"wc_"+this.id+"_checkout_validate_nonce",value:this.ajax_wc_checkout_validate_nonce});return $.ajax({url:ajax_url,method:"post",cache:false,data:form_data,complete:response=>{var result=response.responseJSON;if(result.hasOwnProperty("result")&&"failure"===result.result){$(result.messages).map(message=>{var errors=[];$(message).children("li").each(()=>{errors.push($(this).text().trim())});return square_errors.unshift(...errors)})}else if(result.hasOwnProperty("success")&&!result.success){square_errors.unshift(...result.data.messages)}square_handler.render_errors(square_errors)}})}}window.WC_Square_Payment_Form_Handler=WC_Square_Payment_Form_Handler});
|
build/index.asset.php
CHANGED
@@ -1 +1 @@
|
|
1 |
-
<?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '
|
1 |
+
<?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => 'fb7d2eefc86f7c746ceb39c3c41889c7');
|
build/index.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=30)}([function(e,t){e.exports=window.wp.element},function(e,t){e.exports=function(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=window.React},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t};Object.defineProperty(t,"__esModule",{value:!0});var a=n(r(2));t.Context=a.createContext({applePayState:"loading",formId:"",googlePayState:"loading",masterpassState:"loading",onCreateNonce:function(){},onVerifyBuyer:function(e,t,r){}}),t.default=t.Context},function(e,t,r){"use strict";function n(e){for(var r in e)t.hasOwnProperty(r)||(t[r]=e[r])}Object.defineProperty(t,"__esModule",{value:!0});var a=r(8);n(r(15)),n(r(3)),n(r(16)),n(r(17)),n(r(18)),n(r(19)),n(r(20)),n(r(21)),n(r(22)),n(r(23)),n(r(24)),n(r(8)),t.default=a.SquarePaymentForm},function(e,t){e.exports=window.wp.i18n},function(e,t){e.exports=window.regeneratorRuntime},function(e,t,r){var n=r(25),a=r(26),o=r(27),i=r(29);e.exports=function(e,t){return n(e)||a(e,t)||o(e,t)||i()},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(14)),l=a(r(3));t.SquarePaymentForm=function(e){var t=o.useState("loading"),r=t[0],n=t[1],a=o.useState("loading"),c=a[0],u=a[1],s=o.useState("loading"),d=s[0],f=s[1],p=o.useState(""),m=p[0],v=p[1],y=o.useState(!1),b=y[0],g=y[1],h=o.useState(void 0),_=h[0],O=h[1],C=o.useState(!1),S=C[0],E=C[1],j=i.default((function(t,r,n,a,o,i){!t&&e.createVerificationDetails?_&&_.verifyBuyer(r,e.createVerificationDetails(),(function(t,l){e.cardNonceResponseReceived(t?[t]:null,r,n,l?l.token:void 0,a,o,i)})):e.cardNonceResponseReceived(t,r,n,"",a,o,i)}));function x(t){var r=Object.keys(t);r.includes("masterpass")&&f(!0===t.masterpass?"ready":"unavailable"),r.includes("applePay")&&n(!0===t.applePay?"ready":"unavailable"),r.includes("googlePay")&&u(!0===t.googlePay?"ready":"unavailable"),e.methodsSupported&&e.methodsSupported(t)}var w=function(){E(!0),e.paymentFormLoaded&&e.paymentFormLoaded()};if(o.useEffect((function(){S&&_&&(_.recalculateSize(),e.postalCode&&_.setPostalCode(e.postalCode()),e.focusField&&_.focus(e.focusField()))}),[S,_]),o.useEffect((function(){!function(t,r){if(document.getElementById("sq-payment-form-script")&&"function"==typeof SqPaymentForm)t&&t();else{var n=document.createElement("script");n.id="sq-payment-form-script",e.sandbox?n.src="https://js.squareupsandbox.com/v2/paymentform":n.src="https://js.squareup.com/v2/paymentform",n.onload=function(){t&&t()},n.onerror=function(){r&&r()},document.body.appendChild(n)}}((function(){return g(!0)}),(function(){return v("Unable to load Square payment library")}))}),[]),o.useEffect((function(){return function(){if(!(!b||_||m.length>0))try{var t=new SqPaymentForm(function(e){var t={apiWrapper:e.apiWrapper,applicationId:e.applicationId,autoBuild:!1,callbacks:{cardNonceResponseReceived:e.cardNonceResponseReceived?j:null,createPaymentRequest:e.createPaymentRequest,inputEventReceived:e.inputEventReceived,methodsSupported:x,paymentFormLoaded:w,shippingContactChanged:e.shippingContactChanged,shippingOptionChanged:e.shippingOptionChanged,unsupportedBrowserDetected:e.unsupportedBrowserDetected},locationId:e.locationId};return document.getElementById(e.formId+"-sq-card")?t.card={elementId:e.formId+"-sq-card",inputStyle:e.inputStyles&&e.inputStyles[0]}:document.getElementById(e.formId+"-sq-gift-card")?(t.giftCard={elementId:e.formId+"-sq-gift-card",placeholder:e.placeholderGiftCard||"• • • • • • • • • • • • • • • •"},t.inputClass=e.inputClass||"sq-input",t.inputStyles=e.inputStyles):(t.inputClass=e.inputClass||"sq-input",t.inputStyles=e.inputStyles,document.getElementById(e.formId+"-sq-apple-pay")&&(t.applePay={elementId:e.formId+"-sq-apple-pay"}),document.getElementById(e.formId+"-sq-google-pay")&&(t.googlePay={elementId:e.formId+"-sq-google-pay"}),document.getElementById(e.formId+"-sq-masterpass")&&(t.masterpass={elementId:e.formId+"-sq-masterpass"}),document.getElementById(e.formId+"-sq-card-number")&&(t.cardNumber={elementId:e.formId+"-sq-card-number",placeholder:e.placeholderCreditCard||"• • • • • • • • • • • • • • • •"}),document.getElementById(e.formId+"-sq-cvv")&&(t.cvv={elementId:e.formId+"-sq-cvv",placeholder:e.placeholderCVV||"CVV "}),document.getElementById(e.formId+"-sq-postal-code")?t.postalCode={elementId:e.formId+"-sq-postal-code",placeholder:e.placeholderPostal||"12345"}:t.postalCode=!1,document.getElementById(e.formId+"-sq-expiration-date")&&(t.expirationDate={elementId:e.formId+"-sq-expiration-date",placeholder:e.placeholderExpiration||"MM/YY"})),t}(e));t.build(),O(t)}catch(e){var r=e.message||"Unable to build Square payment form";v(r)}}(),function(){_&&(_.destroy(),O(void 0))}}),[b]),o.useEffect((function(){if(_&&"ready"===d){var t=document.getElementById(e.formId+"-sq-masterpass");if(t){var r=_.masterpassImageUrl();t.style.display="inline-block",t.style.backgroundImage="url("+r+")"}}}),[_,d]),m)return o.default.createElement("div",{className:"sq-payment-form"},o.default.createElement("div",{className:"sq-error-message"},m));var P={applePayState:r,formId:e.formId,googlePayState:c,masterpassState:d,onCreateNonce:function(){_&&_.requestCardNonce()},onVerifyBuyer:function(e,t,r){_&&_.verifyBuyer(e,t,r)}};return o.default.createElement(l.default.Provider,{value:P},o.default.createElement("div",{id:e.formId,className:"sq-payment-form"},e.children))},t.SquarePaymentForm.defaultProps={apiWrapper:"reactjs/0.7.2",formId:"sq-payment-form",inputStyles:[{_mozOsxFontSmoothing:"grayscale",_webkitFontSmoothing:"antialiased",backgroundColor:"transparent",color:"#373F4A",fontFamily:"Helvetica Neue",fontSize:"16px",lineHeight:"24px",padding:"16px",placeholderColor:"#CCC"}],sandbox:!1}},function(e,t){e.exports=window.wc.wcBlocksRegistry},function(e,t,r){var n=r(13);e.exports=function(e,t){if(null==e)return{};var r,a,o=n(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)r=i[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){function r(e,t,r,n,a,o,i){try{var l=e[o](i),c=l.value}catch(e){return void r(e)}l.done?t(c):Promise.resolve(c).then(n,a)}e.exports=function(e){return function(){var t=this,n=arguments;return new Promise((function(a,o){var i=e.apply(t,n);function l(e){r(i,a,o,l,c,"next",e)}function c(e){r(i,a,o,l,c,"throw",e)}l(void 0)}))}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=window.wc.wcSettings},function(e,t){e.exports=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(2);t.default=function(e){var t=n.useRef(e);return n.useLayoutEffect((function(){t.current=e}),[e]),n.useCallback((function(){for(var e=[],r=0;r<arguments.length;r++)e[r]=arguments[r];return t.current.apply(t,e)}),[])}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.ApplePayButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-apple-pay",className:"sq-apple-pay",style:{display:"ready"===t.applePayState?"block":"none"}}),"loading"===t.applePayState&&e.loadingView,"unavailable"===t.applePayState&&e.unavailableView)}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.CreditCardCVVInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-cvv"}))},t.CreditCardCVVInput.defaultProps={label:"CVV"}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.CreditCardExpirationDateInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-expiration-date"}))},t.CreditCardExpirationDateInput.defaultProps={label:"Expiration"}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.CreditCardNumberInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-card-number"}))},t.CreditCardNumberInput.defaultProps={label:"Credit Card"}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.CreditCardPostalCodeInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-postal-code"}))},t.CreditCardPostalCodeInput.defaultProps={label:"Postal"}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.CreditCardSubmitButton=function(e){var t=o.useContext(i.default);return o.default.createElement("button",{className:"sq-creditcard",onClick:t.onCreateNonce},e.children?e.children:"Pay")}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.GiftCardInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-gift-card"}))},t.GiftCardInput.defaultProps={label:"Gift Card"}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.GooglePayButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-google-pay",className:"sq-google-pay",style:{display:"ready"===t.googlePayState?"block":"none"}}),"loading"===t.googlePayState&&e.loadingView,"unavailable"===t.googlePayState&&e.unavailableView)}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.MasterpassButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-masterpass",className:"sq-masterpass",style:{display:"ready"===t.masterpassState?"block":"none"}}),"loading"===t.masterpassState&&e.loadingView,"unavailable"===t.masterpassState&&e.unavailableView)}},function(e,t,r){"use strict";var n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=n(r(2)),i=a(r(3));t.SimpleCard=function(){var e=o.useContext(i.default);return o.default.createElement("div",{id:e.formId+"-sq-card"})}},function(e,t){e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,o=[],_n=!0,i=!1;try{for(r=r.call(e);!(_n=(n=r.next()).done)&&(o.push(n.value),!t||o.length!==t);_n=!0);}catch(e){i=!0,a=e}finally{try{_n||null==r.return||r.return()}finally{if(i)throw a}}return o}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,r){var n=r(28);e.exports=function(e,t){if(e){if("string"==typeof e)return n(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,r){"use strict";r.r(t);var n=r(9),a=r(10),o=r.n(a),i=r(0),l=r(5),c=r(4),u=r(1),s=r.n(u),d=r(11),f=r.n(d),p=r(6),m=r.n(p),v=r(12);function y(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return b(e,void 0);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?b(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,a=function(){};return{s:a,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,l=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return i=e.done,e},e:function(e){l=!0,o=e},f:function(){try{i||null==r.return||r.return()}finally{if(l)throw o}}}}function b(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var g=null,h=function(){if(null!==g)return g;var e=Object(v.getSetting)("square_credit_card_data",null);if(!e)throw new Error("Square initialization data is not available");return g={title:e.title||"",applicationId:e.application_id||"",locationId:e.location_id||"",isSandbox:e.is_sandbox||!1,is3dsEnabled:e.is_3ds_enabled||!1,inputStyles:e.input_styles||[],availableCardTypes:e.available_card_types||{},loggingEnabled:e.logging_enabled||!1,generalError:e.general_error||"",showSavedCards:e.show_saved_cards||!1,showSaveOption:e.show_save_option||!1,supports:e.supports||{}}},_=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{logs:[],notices:[]},r=!1;if(e){var n=["none","cardNumber","expirationDate","cvv","postalCode"];e.length>=1&&e.sort((function(e,t){return n.indexOf(e.field)-n.indexOf(t.field)}));var a,o=y(e);try{for(o.s();!(a=o.n()).done;){var i=a.value;"UNSUPPORTED_CARD_BRAND"===i.type||"VALIDATION_ERROR"===i.type?(t.notices.push(i.message.replace(/CVV/,"CSC")),r=!0):C(i,t)}}catch(e){o.e(e)}finally{o.f()}}r||t.notices.push(h().generalError)},O=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"notice";h().loggingEnabled&&("error"===t?console.error(e):console.log(e))},C=function(e,t){h().loggingEnabled&&t&&t.logs.push(e)};function S(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function E(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?S(Object(r),!0).forEach((function(t){s()(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):S(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}var j=function(e){var t=e.checkoutFormHandler,r=e.eventRegistration,n=e.emitResponse,a=Object(i.useContext)(c.Context),o=r.onPaymentProcessing,l=r.onCheckoutAfterProcessingWithError,u=r.onCheckoutAfterProcessingWithSuccess;return function(e,t,r,n,a,o){var l=Object(i.useRef)(r);Object(i.useEffect)((function(){l.current=r}),[r]),Object(i.useEffect)((function(){return e(function(){var e=f()(m.a.mark((function e(){var r,i,c,u,s,d;return m.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r={type:t.responseTypes.SUCCESS},i={nonce:"",notices:[],logs:[]},e.next=4,a(l.current);case 4:if(c=e.sent,u=E(E({},i),c),s=u.token||u.nonce,!h().is3dsEnabled||!s){e.next=14;break}return e.next=10,o(l.current,s);case 10:d=e.sent,u.verificationToken=d.verificationToken||"",u.logs=u.logs.concat(d.log||[]),u.errors=u.notices.concat(d.errors||[]);case 14:return s||u.logs.length>0?r.meta={paymentMethodData:n(u)}:u.notices.length>0&&(r.type=t.responseTypes.ERROR,r.message=u.notices),e.abrupt("return",r);case 16:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}())}),[e,t.responseTypes.SUCCESS,t.responseTypes.ERROR,a,o,n])}(o,n,a,t.getPaymentMethodData,t.createNonce,t.verifyBuyer),function(e,t,r){Object(i.useEffect)((function(){var n=function(e){var t={type:r.responseTypes.SUCCESS},n=e.processingResponse,a=n.paymentStatus,o=n.paymentDetails;return a===r.responseTypes.ERROR&&o.checkoutNotices&&(t={type:r.responseTypes.ERROR,message:JSON.parse(o.checkoutNotices),messageContext:r.noticeContexts.PAYMENTS,retry:!0}),t},a=e(n),o=t(n);return function(){a(),o()}}),[e,t,r.noticeContexts.PAYMENTS,r.responseTypes.ERROR,r.responseTypes.SUCCESS])}(l,u,n),null},x=r(7),w=r.n(x);function P(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return I(e,void 0);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?I(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,a=function(){};return{s:a,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,l=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return i=e.done,e},e:function(e){l=!0,o=e},f:function(){try{i||null==r.return||r.return()}finally{if(l)throw o}}}}function I(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var q=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n=Object(i.useState)(!1),a=w()(n,2),o=a[0],l=a[1],c=Object(i.useState)(""),u=w()(c,2),d=u[0],f=u[1],p=Object(i.useRef)(null),m=Object(i.useRef)(null),v=Object(i.useMemo)((function(){var n=t&&!r?"STORE":"CHARGE",a={billingContact:{familyName:e.billingData.last_name||"",givenName:e.billingData.first_name||"",email:e.billingData.email||"",country:e.billingData.country||"",region:e.billingData.state||"",city:e.billingData.city||"",postalCode:e.billingData.postcode||"",phone:e.billingData.phone||"",addressLines:[e.billingData.address_1||"",e.billingData.address_2||""]},intent:n};return"CHARGE"===n&&(a.amount=(e.cartTotal.value/100).toString(),a.currencyCode=e.currency.code),a}),[e.billingData,e.cartTotal.value,e.currency.code,t,r]),y=Object(i.useCallback)((function(e){var n,a,o,i=e.cardData,l=e.nonce,c=e.verificationToken,u=e.notices,f=e.logs;return o={},s()(o,"wc-".concat("square-credit-card","-card-type"),d||""),s()(o,"wc-".concat("square-credit-card","-last-four"),(null==i?void 0:i.last_4)||""),s()(o,"wc-".concat("square-credit-card","-exp-month"),(null==i||null===(n=i.exp_month)||void 0===n?void 0:n.toString())||""),s()(o,"wc-".concat("square-credit-card","-exp-year"),(null==i||null===(a=i.exp_year)||void 0===a?void 0:a.toString())||""),s()(o,"wc-".concat("square-credit-card","-payment-postcode"),(null==i?void 0:i.billing_postal_code)||""),s()(o,"wc-".concat("square-credit-card","-payment-nonce"),l||""),s()(o,"wc-".concat("square-credit-card","-payment-token"),r||""),s()(o,"wc-".concat("square-credit-card","-buyer-verification-token"),c||""),s()(o,"wc-".concat("square-credit-card","-tokenize-payment-method"),t||!1),s()(o,"log-data",f.length>0?JSON.stringify(f):""),s()(o,"checkout-notices",u.length>0?JSON.stringify(u):""),o}),[d,t,r]),b=function(e,t,r){var n={notices:[],logs:[]};e?_(e,n):t?(C(r,n),O("Card data received"),O(r),n.cardData=r,n.nonce=t):(C("Nonce is missing from the Square response",n),O("Nonce is missing from the Square response","error"),_([],n)),p.current&&p.current(n)},g=Object(i.useCallback)((function(e){if(!r){var t=new Promise((function(e){return p.current=e}));return e.onCreateNonce(),t}return Promise.resolve({token:r})}),[r]),S=Object(i.useCallback)((function(e,t){var r=new Promise((function(e){return m.current=e}));return e.onVerifyBuyer(t,v,E),r}),[v,E]),E=Object(i.useCallback)((function(e,t){var r={notices:[],logs:[]};if(e){var n,a=P(e);try{for(a.s();!(n=a.n()).done;){var o=n.value;o.field||(o.field="none")}}catch(e){a.e(e)}finally{a.f()}_(e,r)}t&&t.token?r.verificationToken=t.token:(C("Verification token is missing from the Square response",r),O("Verification token is missing from the Square response","error"),_([],r)),m.current&&m.current(r)}),[m]),j=Object(i.useCallback)((function(e){if("cardBrandChanged"===e.eventType){var t=e.cardBrand,r="plain";null!==t&&"unknown"!==t||(r=""),null!==h().availableCardTypes[t]&&(r=h().availableCardTypes[t]),O("Card brand changed to ".concat(t)),f(r)}}),[]),x=Object(i.useCallback)((function(){return e.billingData.postcode||""}),[e.billingData.postcode]);return{cardNonceResponseReceived:b,handleInputReceived:j,isLoaded:o,setLoaded:l,getPostalCode:x,cardType:d,createNonce:g,verifyBuyer:S,getPaymentMethodData:y}},M=function(e){var t=e.cardType;return Object(i.createElement)("fieldset",{id:"wc-square-credit-card-credit-card-form"},Object(i.createElement)("span",{className:"sq-label"},Object(l.__)("Card Number","woocommerce-square")),Object(i.createElement)("div",{id:"wc-square-credit-card-account-number-hosted",className:"wc-square-credit-card-hosted-field ".concat(t?"card-type-".concat(t):"")},Object(i.createElement)(c.CreditCardNumberInput,{label:""})),Object(i.createElement)("div",{className:"sq-form-third"},Object(i.createElement)("span",{className:"sq-label"},Object(l.__)("Expiration (MM/YY)","woocommerce-square")),Object(i.createElement)("div",{id:"wc-square-credit-card-expiry-hosted",className:"wc-square-credit-card-hosted-field"},Object(i.createElement)(c.CreditCardExpirationDateInput,{label:""}))),Object(i.createElement)("div",{className:"sq-form-third"},Object(i.createElement)("span",{className:"sq-label"},Object(l.__)("Card Security Code","woocommerce-square")),Object(i.createElement)("div",{id:"wc-square-credit-card-csc-hosted",className:"wc-square-credit-card-hosted-field"},Object(i.createElement)(c.CreditCardCVVInput,{label:""}))),Object(i.createElement)("div",{className:"sq-form-third"},Object(i.createElement)("span",{className:"sq-label"},Object(l.__)("Postal code","woocommerce-square")),Object(i.createElement)("div",{id:"wc-square-credit-card-postal-code-hosted",className:"wc-square-credit-card-hosted-field"},Object(i.createElement)(c.CreditCardPostalCodeInput,{label:""}))))},R=function(e){var t=e.billing,r=e.eventRegistration,n=e.emitResponse,a=e.shouldSavePayment,o=q(t,a);return Object(i.createElement)(c.SquarePaymentForm,{formId:"square-credit-card",sandbox:h().isSandbox,applicationId:h().applicationId,locationId:h().locationId,inputStyles:h().inputStyles,placeholderCreditCard:"•••• •••• •••• ••••",placeholderExpiration:Object(l.__)("MM / YY","woocommerce-square"),placeholderCVV:Object(l.__)("CSC","woocommerce-square"),postalCode:o.getPostalCode,cardNonceResponseReceived:o.cardNonceResponseReceived,inputEventReceived:o.handleInputReceived,paymentFormLoaded:function(){return o.setLoaded(!0)}},Object(i.createElement)(M,{cardType:o.cardType}),o.isLoaded&&Object(i.createElement)(j,{checkoutFormHandler:o,eventRegistration:r,emitResponse:n}))},N=["RenderedComponent"],k=function(e){var t=e.RenderedComponent,r=o()(e,N);return Object(i.createElement)(t,r)},D={name:"square-credit-card",label:Object(i.createElement)((function(e){var t=e.components.PaymentMethodLabel;return Object(i.createElement)(t,{text:h().title})}),null),content:Object(i.createElement)(k,{RenderedComponent:R}),edit:Object(i.createElement)(k,{RenderedComponent:R}),savedTokenComponent:Object(i.createElement)(k,{RenderedComponent:function(e){var t=e.billing,r=e.eventRegistration,n=e.emitResponse,a=e.token,o=q(t,!1,a);return Object(i.createElement)(c.SquarePaymentForm,{formId:"square-credit-card-saved-card",sandbox:h().isSandbox,applicationId:h().applicationId,locationId:h().locationId,paymentFormLoaded:function(){return o.setLoaded(!0)}},o.isLoaded&&Object(i.createElement)(j,{checkoutFormHandler:o,eventRegistration:r,emitResponse:n}))}}),paymentMethodId:"square_credit_card",ariaLabel:"Square",canMakePayment:function(){return!(!h().applicationId||!h().locationId)},supports:{features:h().supports,showSavedCards:h().showSavedCards,showSaveOption:h().showSaveOption}};Object(n.registerPaymentMethod)(D)}]);
|
1 |
+
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=30)}([function(e,t){e.exports=window.wp.element},function(e,t){e.exports=window.regeneratorRuntime},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=window.React},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t};Object.defineProperty(t,"__esModule",{value:!0});var a=r(n(3));t.Context=a.createContext({applePayState:"loading",formId:"",googlePayState:"loading",masterpassState:"loading",onCreateNonce:function(){},onVerifyBuyer:function(e,t,n){}}),t.default=t.Context},function(e,t){function n(e,t,n,r,a,o,i){try{var u=e[o](i),l=u.value}catch(e){return void n(e)}u.done?t(l):Promise.resolve(l).then(r,a)}e.exports=function(e){return function(){var t=this,r=arguments;return new Promise((function(a,o){var i=e.apply(t,r);function u(e){n(i,a,o,u,l,"next",e)}function l(e){n(i,a,o,u,l,"throw",e)}u(void 0)}))}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,n){var r=n(25),a=n(26),o=n(27),i=n(29);e.exports=function(e,t){return r(e)||a(e,t)||o(e,t)||i()},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,n){"use strict";function r(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}Object.defineProperty(t,"__esModule",{value:!0});var a=n(8);r(n(15)),r(n(4)),r(n(16)),r(n(17)),r(n(18)),r(n(19)),r(n(20)),r(n(21)),r(n(22)),r(n(23)),r(n(24)),r(n(8)),t.default=a.SquarePaymentForm},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(14)),u=a(n(4));t.SquarePaymentForm=function(e){var t=o.useState("loading"),n=t[0],r=t[1],a=o.useState("loading"),l=a[0],s=a[1],c=o.useState("loading"),d=c[0],f=c[1],p=o.useState(""),m=p[0],v=p[1],y=o.useState(!1),b=y[0],g=y[1],h=o.useState(void 0),_=h[0],O=h[1],C=o.useState(!1),S=C[0],x=C[1],P=i.default((function(t,n,r,a,o,i){!t&&e.createVerificationDetails?_&&_.verifyBuyer(n,e.createVerificationDetails(),(function(t,u){e.cardNonceResponseReceived(t?[t]:null,n,r,u?u.token:void 0,a,o,i)})):e.cardNonceResponseReceived(t,n,r,"",a,o,i)}));function E(t){var n=Object.keys(t);n.includes("masterpass")&&f(!0===t.masterpass?"ready":"unavailable"),n.includes("applePay")&&r(!0===t.applePay?"ready":"unavailable"),n.includes("googlePay")&&s(!0===t.googlePay?"ready":"unavailable"),e.methodsSupported&&e.methodsSupported(t)}var j=function(){x(!0),e.paymentFormLoaded&&e.paymentFormLoaded()};if(o.useEffect((function(){S&&_&&(_.recalculateSize(),e.postalCode&&_.setPostalCode(e.postalCode()),e.focusField&&_.focus(e.focusField()))}),[S,_]),o.useEffect((function(){!function(t,n){if(document.getElementById("sq-payment-form-script")&&"function"==typeof SqPaymentForm)t&&t();else{var r=document.createElement("script");r.id="sq-payment-form-script",e.sandbox?r.src="https://js.squareupsandbox.com/v2/paymentform":r.src="https://js.squareup.com/v2/paymentform",r.onload=function(){t&&t()},r.onerror=function(){n&&n()},document.body.appendChild(r)}}((function(){return g(!0)}),(function(){return v("Unable to load Square payment library")}))}),[]),o.useEffect((function(){return function(){if(!(!b||_||m.length>0))try{var t=new SqPaymentForm(function(e){var t={apiWrapper:e.apiWrapper,applicationId:e.applicationId,autoBuild:!1,callbacks:{cardNonceResponseReceived:e.cardNonceResponseReceived?P:null,createPaymentRequest:e.createPaymentRequest,inputEventReceived:e.inputEventReceived,methodsSupported:E,paymentFormLoaded:j,shippingContactChanged:e.shippingContactChanged,shippingOptionChanged:e.shippingOptionChanged,unsupportedBrowserDetected:e.unsupportedBrowserDetected},locationId:e.locationId};return document.getElementById(e.formId+"-sq-card")?t.card={elementId:e.formId+"-sq-card",inputStyle:e.inputStyles&&e.inputStyles[0]}:document.getElementById(e.formId+"-sq-gift-card")?(t.giftCard={elementId:e.formId+"-sq-gift-card",placeholder:e.placeholderGiftCard||"• • • • • • • • • • • • • • • •"},t.inputClass=e.inputClass||"sq-input",t.inputStyles=e.inputStyles):(t.inputClass=e.inputClass||"sq-input",t.inputStyles=e.inputStyles,document.getElementById(e.formId+"-sq-apple-pay")&&(t.applePay={elementId:e.formId+"-sq-apple-pay"}),document.getElementById(e.formId+"-sq-google-pay")&&(t.googlePay={elementId:e.formId+"-sq-google-pay"}),document.getElementById(e.formId+"-sq-masterpass")&&(t.masterpass={elementId:e.formId+"-sq-masterpass"}),document.getElementById(e.formId+"-sq-card-number")&&(t.cardNumber={elementId:e.formId+"-sq-card-number",placeholder:e.placeholderCreditCard||"• • • • • • • • • • • • • • • •"}),document.getElementById(e.formId+"-sq-cvv")&&(t.cvv={elementId:e.formId+"-sq-cvv",placeholder:e.placeholderCVV||"CVV "}),document.getElementById(e.formId+"-sq-postal-code")?t.postalCode={elementId:e.formId+"-sq-postal-code",placeholder:e.placeholderPostal||"12345"}:t.postalCode=!1,document.getElementById(e.formId+"-sq-expiration-date")&&(t.expirationDate={elementId:e.formId+"-sq-expiration-date",placeholder:e.placeholderExpiration||"MM/YY"})),t}(e));t.build(),O(t)}catch(e){var n=e.message||"Unable to build Square payment form";v(n)}}(),function(){_&&(_.destroy(),O(void 0))}}),[b]),o.useEffect((function(){if(_&&"ready"===d){var t=document.getElementById(e.formId+"-sq-masterpass");if(t){var n=_.masterpassImageUrl();t.style.display="inline-block",t.style.backgroundImage="url("+n+")"}}}),[_,d]),m)return o.default.createElement("div",{className:"sq-payment-form"},o.default.createElement("div",{className:"sq-error-message"},m));var w={applePayState:n,formId:e.formId,googlePayState:l,masterpassState:d,onCreateNonce:function(){_&&_.requestCardNonce()},onVerifyBuyer:function(e,t,n){_&&_.verifyBuyer(e,t,n)}};return o.default.createElement(u.default.Provider,{value:w},o.default.createElement("div",{id:e.formId,className:"sq-payment-form"},e.children))},t.SquarePaymentForm.defaultProps={apiWrapper:"reactjs/0.7.2",formId:"sq-payment-form",inputStyles:[{_mozOsxFontSmoothing:"grayscale",_webkitFontSmoothing:"antialiased",backgroundColor:"transparent",color:"#373F4A",fontFamily:"Helvetica Neue",fontSize:"16px",lineHeight:"24px",padding:"16px",placeholderColor:"#CCC"}],sandbox:!1}},function(e,t){e.exports=window.wc.wcBlocksRegistry},function(e,t,n){var r=n(12);e.exports=function(e,t){if(null==e)return{};var n,a,o=r(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=window.wc.wcSettings},function(e,t){e.exports=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=window.wp.i18n},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3);t.default=function(e){var t=r.useRef(e);return r.useLayoutEffect((function(){t.current=e}),[e]),r.useCallback((function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return t.current.apply(t,e)}),[])}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.ApplePayButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-apple-pay",className:"sq-apple-pay",style:{display:"ready"===t.applePayState?"block":"none"}}),"loading"===t.applePayState&&e.loadingView,"unavailable"===t.applePayState&&e.unavailableView)}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.CreditCardCVVInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-cvv"}))},t.CreditCardCVVInput.defaultProps={label:"CVV"}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.CreditCardExpirationDateInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-expiration-date"}))},t.CreditCardExpirationDateInput.defaultProps={label:"Expiration"}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.CreditCardNumberInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-card-number"}))},t.CreditCardNumberInput.defaultProps={label:"Credit Card"}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.CreditCardPostalCodeInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-postal-code"}))},t.CreditCardPostalCodeInput.defaultProps={label:"Postal"}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.CreditCardSubmitButton=function(e){var t=o.useContext(i.default);return o.default.createElement("button",{className:"sq-creditcard",onClick:t.onCreateNonce},e.children?e.children:"Pay")}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.GiftCardInput=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,e.label&&o.default.createElement("span",{className:"sq-label"},e.label),o.default.createElement("div",{id:t.formId+"-sq-gift-card"}))},t.GiftCardInput.defaultProps={label:"Gift Card"}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.GooglePayButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-google-pay",className:"sq-google-pay",style:{display:"ready"===t.googlePayState?"block":"none"}}),"loading"===t.googlePayState&&e.loadingView,"unavailable"===t.googlePayState&&e.unavailableView)}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.MasterpassButton=function(e){var t=o.useContext(i.default);return o.default.createElement("div",null,o.default.createElement("button",{id:t.formId+"-sq-masterpass",className:"sq-masterpass",style:{display:"ready"===t.masterpassState?"block":"none"}}),"loading"===t.masterpassState&&e.loadingView,"unavailable"===t.masterpassState&&e.unavailableView)}},function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(3)),i=a(n(4));t.SimpleCard=function(){var e=o.useContext(i.default);return o.default.createElement("div",{id:e.formId+"-sq-card"})}},function(e,t){e.exports=function(e){if(Array.isArray(e))return e},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o=[],_n=!0,i=!1;try{for(n=n.call(e);!(_n=(r=n.next()).done)&&(o.push(r.value),!t||o.length!==t);_n=!0);}catch(e){i=!0,a=e}finally{try{_n||null==n.return||n.return()}finally{if(i)throw a}}return o}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,n){var r=n(28);e.exports=function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")},e.exports.__esModule=!0,e.exports.default=e.exports},function(e,t,n){"use strict";n.r(t);var r=n(9),a=n(10),o=n.n(a),i=n(0),u=(n(13),n(7)),l=n(2),s=n.n(l),c=n(5),d=n.n(c),f=n(1),p=n.n(f),m=n(11);function v(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return y(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?y(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,u=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return i=e.done,e},e:function(e){u=!0,o=e},f:function(){try{i||null==n.return||n.return()}finally{if(u)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var b=null,g=function(){if(null!==b)return b;var e=Object(m.getSetting)("square_credit_card_data",null);if(!e)throw new Error("Square initialization data is not available");return b={title:e.title||"",applicationId:e.application_id||"",locationId:e.location_id||"",isSandbox:e.is_sandbox||!1,is3dsEnabled:e.is_3ds_enabled||!1,inputStyles:e.input_styles||[],availableCardTypes:e.available_card_types||{},loggingEnabled:e.logging_enabled||!1,generalError:e.general_error||"",showSavedCards:e.show_saved_cards||!1,showSaveOption:e.show_save_option||!1,supports:e.supports||{}}},h=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{logs:[],notices:[]},n=!1;if(e){var r=["none","cardNumber","expirationDate","cvv","postalCode"];e.length>=1&&e.sort((function(e,t){return r.indexOf(e.field)-r.indexOf(t.field)}));var a,o=v(e);try{for(o.s();!(a=o.n()).done;){var i=a.value;"UNSUPPORTED_CARD_BRAND"===i.type||"VALIDATION_ERROR"===i.type?(t.notices.push(i.message.replace(/CVV/,"CSC")),n=!0):O(i,t)}}catch(e){o.e(e)}finally{o.f()}}n||t.notices.push(g().generalError)},_=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"notice";g().loggingEnabled&&("error"===t?console.error(e):console.log(e))},O=function(e,t){g().loggingEnabled&&t&&t.logs.push(e)};function C(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function S(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?C(Object(n),!0).forEach((function(t){s()(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):C(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var x=Object(i.createContext)(!1),P=function(e){var t=e.checkoutFormHandler,n=e.eventRegistration,r=e.emitResponse,a=Object(i.useContext)(x),o=n.onPaymentProcessing,u=n.onCheckoutAfterProcessingWithError,l=n.onCheckoutAfterProcessingWithSuccess;return function(e,t,n,r,a,o){var u=Object(i.useRef)(n);Object(i.useEffect)((function(){u.current=n}),[n]),Object(i.useEffect)((function(){return e(function(){var e=d()(p.a.mark((function e(){var n,i,l,s,c,d,f,m;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return l={type:t.responseTypes.SUCCESS},s={nonce:"",notices:[],logs:[]},e.next=4,a(u.current.card);case 4:if(c=e.sent,d=S(S({},s),{},{nonce:c.token}),null!=c&&null!==(n=c.details)&&void 0!==n&&n.card&&null!=c&&null!==(i=c.details)&&void 0!==i&&i.billing&&(d.cardData=S(S({},c.details.card),c.details.billing)),f=d.token||d.nonce,!g().is3dsEnabled||!f){e.next=15;break}return e.next=11,o(u.current.payments,f);case 11:m=e.sent,d.verificationToken=m.verificationToken||"",d.logs=d.logs.concat(m.log||[]),d.errors=d.notices.concat(m.errors||[]);case 15:return f||d.logs.length>0?l.meta={paymentMethodData:r(d)}:d.notices.length>0&&(l.type=t.responseTypes.ERROR,l.message=d.notices),e.abrupt("return",l);case 17:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}())}),[e,t.responseTypes.SUCCESS,t.responseTypes.ERROR,a,o,r])}(o,r,a,t.getPaymentMethodData,t.createNonce,t.verifyBuyer),function(e,t,n){Object(i.useEffect)((function(){var r=function(e){var t={type:n.responseTypes.SUCCESS},r=e.processingResponse,a=r.paymentStatus,o=r.paymentDetails;return a===n.responseTypes.ERROR&&o.checkoutNotices&&(t={type:n.responseTypes.ERROR,message:JSON.parse(o.checkoutNotices),messageContext:n.noticeContexts.PAYMENTS,retry:!0}),t},a=e(r),o=t(r);return function(){a(),o()}}),[e,t,n.noticeContexts.PAYMENTS,n.responseTypes.ERROR,n.responseTypes.SUCCESS])}(u,l,r),null},E=n(6),j=n.n(E),w=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=Object(i.useState)(!1),a=j()(r,2),o=a[0],u=a[1],l=Object(i.useState)(""),c=j()(l,2),f=c[0],m=c[1],v=Object(i.useRef)(null),y=Object(i.useRef)(null),b=Object(i.useMemo)((function(){var r=t&&!n?"STORE":"CHARGE",a={billingContact:{familyName:e.billingData.last_name||"",givenName:e.billingData.first_name||"",email:e.billingData.email||"",country:e.billingData.country||"",region:e.billingData.state||"",city:e.billingData.city||"",postalCode:e.billingData.postcode||"",phone:e.billingData.phone||"",addressLines:[e.billingData.address_1||"",e.billingData.address_2||""]},intent:r};return"CHARGE"===r&&(a.amount=(e.cartTotal.value/100).toString(),a.currencyCode=e.currency.code),a}),[e.billingData,e.cartTotal.value,e.currency.code,t,n]),C=Object(i.useCallback)((function(e){var r,a,o,i=e.cardData,u=void 0===i?{}:i,l=e.nonce,c=e.verificationToken,d=e.notices,p=e.logs;return o={},s()(o,"wc-".concat("square-credit-card","-card-type"),f||""),s()(o,"wc-".concat("square-credit-card","-last-four"),(null==u?void 0:u.last4)||""),s()(o,"wc-".concat("square-credit-card","-exp-month"),(null==u||null===(r=u.expMonth)||void 0===r?void 0:r.toString())||""),s()(o,"wc-".concat("square-credit-card","-exp-year"),(null==u||null===(a=u.expYear)||void 0===a?void 0:a.toString())||""),s()(o,"wc-".concat("square-credit-card","-payment-postcode"),(null==u?void 0:u.postalCode)||""),s()(o,"wc-".concat("square-credit-card","-payment-nonce"),l||""),s()(o,"wc-".concat("square-credit-card","-payment-token"),n||""),s()(o,"wc-".concat("square-credit-card","-buyer-verification-token"),c||""),s()(o,"wc-".concat("square-credit-card","-tokenize-payment-method"),t||!1),s()(o,"log-data",p.length>0?JSON.stringify(p):""),s()(o,"checkout-notices",d.length>0?JSON.stringify(d):""),o}),[f,t,n]),S=function(e,t,n){var r={notices:[],logs:[]};e?h(e,r):t?(O(n,r),_("Card data received"),_(n),r.cardData=n,r.nonce=t):(O("Nonce is missing from the Square response",r),_("Nonce is missing from the Square response","error"),h([],r)),v.current&&v.current(r)},x=Object(i.useCallback)(function(){var e=d()(p.a.mark((function e(t){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n){e.next=4;break}return e.next=3,t.tokenize();case 3:return e.abrupt("return",e.sent);case 4:return e.abrupt("return",n);case 5:case"end":return e.stop()}}),e)})));return function(_x){return e.apply(this,arguments)}}(),[n]),P=Object(i.useCallback)(function(){var e=d()(p.a.mark((function e(t,n){var r;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,t.verifyBuyer(n,b);case 3:return r=e.sent,e.abrupt("return",E(r));case 7:e.prev=7,e.t0=e.catch(0),h([e.t0]);case 10:return e.abrupt("return",!1);case 11:case"end":return e.stop()}}),e,null,[[0,7]])})));return function(t,n){return e.apply(this,arguments)}}(),[b,E]),E=Object(i.useCallback)((function(e){var t={notices:[],logs:[]};return e&&e.token?t.verificationToken=e.token:(O("Verification token is missing from the Square response",t),_("Verification token is missing from the Square response","error"),h([],t)),t}),[y]),w=Object(i.useCallback)((function(e){if("cardBrandChanged"===e.eventType){var t=e.cardBrand,n="plain";null!==t&&"unknown"!==t||(n=""),null!==g().availableCardTypes[t]&&(n=g().availableCardTypes[t]),_("Card brand changed to ".concat(t)),m(n)}}),[]),I=Object(i.useCallback)((function(){return e.billingData.postcode||""}),[e.billingData.postcode]);return{cardNonceResponseReceived:S,handleInputReceived:w,isLoaded:o,setLoaded:u,getPostalCode:I,cardType:f,createNonce:x,verifyBuyer:P,getPaymentMethodData:C}},I=function(e){var t=e.children,n=e.defaults.postalCode,r=void 0===n?"":n,a=Object(i.useState)(!1),o=j()(a,2),u=o[0],l=o[1],s=Object(i.useState)(!1),c=j()(s,2),f=c[0],m=c[1],v=g(),y=v.applicationId,b=v.locationId;return Object(i.useEffect)((function(){!u&&window.Square&&l(window.Square.payments(y,b))}),[u]),Object(i.useEffect)((function(){u&&!f&&function(){var e=d()(p.a.mark((function e(){var t;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,u.card({postalCode:r});case 2:t=e.sent,m(t);case 4:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()()}),[u]),u?Object(i.createElement)(x.Provider,{value:{payments:u,card:f}},t):null},q=function(){var e=Object(i.useContext)(x).card,t=Object(i.useRef)(!1);return Object(i.useEffect)((function(){e&&function(){var n=d()(p.a.mark((function n(){return p.a.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:e.attach(t.current);case 1:case"end":return n.stop()}}),n)})));return function(){return n.apply(this,arguments)}}()()}),[e]),Object(i.createElement)("div",{ref:t})},M=function(e){var t=e.billing,n=e.eventRegistration,r=e.emitResponse,a=e.shouldSavePayment,o=w(t,a);return Object(i.createElement)(I,{defaults:{postalCode:o.getPostalCode()}},Object(i.createElement)(q,null),Object(i.createElement)(P,{checkoutFormHandler:o,eventRegistration:n,emitResponse:r}))},R=["RenderedComponent"],k=function(e){var t=e.RenderedComponent,n=o()(e,R);return Object(i.createElement)(t,n)},D={name:"square-credit-card",label:Object(i.createElement)((function(e){var t=e.components.PaymentMethodLabel;return Object(i.createElement)(t,{text:g().title})}),null),content:Object(i.createElement)(k,{RenderedComponent:M}),edit:Object(i.createElement)(k,{RenderedComponent:M}),savedTokenComponent:Object(i.createElement)(k,{RenderedComponent:function(e){var t=e.billing,n=e.eventRegistration,r=e.emitResponse,a=e.token,o=w(t,!1,a);return Object(i.createElement)(u.SquarePaymentForm,{formId:"square-credit-card-saved-card",sandbox:g().isSandbox,applicationId:g().applicationId,locationId:g().locationId,paymentFormLoaded:function(){return o.setLoaded(!0)}},o.isLoaded&&Object(i.createElement)(P,{checkoutFormHandler:o,eventRegistration:n,emitResponse:r}))}}),paymentMethodId:"square_credit_card",ariaLabel:"Square",canMakePayment:function(){return!(!g().applicationId||!g().locationId)},supports:{features:g().supports,showSavedCards:g().showSavedCards,showSaveOption:g().showSaveOption}};Object(r.registerPaymentMethod)(D)}]);
|
changelog.txt
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*** WooCommerce Square Changelog ***
|
2 |
+
|
3 |
+
= 3.0.0 - 2022-05-04 =
|
4 |
+
* New - Upgrade the payment form on checkout to use the latest Square Web Payments SDK. PR#668
|
5 |
+
* Fix - Compatibility issues with WordPress 6.1.0. PR#715
|
6 |
+
* Fix - Sync issues caused by product variations having an empty SKU and incorrectly being set to the variable product (parent product) SKU value. PR#764
|
7 |
+
* Update - Remove admin notice warning of v3.0.0 release. PR#744
|
8 |
+
* Dev - Product importing is now handled by Action Scheduler. PR#698
|
9 |
+
* Dev - Syncing is now handled by Action Scheduler. PR#699
|
10 |
+
* Dev - Manual Sync is now handled by Action Scheduler. PR#710
|
11 |
+
* Dev - Upgrade Action Scheduler to 3.4.0. PR#762
|
12 |
+
* Dev - Updated Square Connect to Square SDK v 15.0.0. PR#673 PR#670 PR#668 PR#664 PR#659 PR#657
|
13 |
+
* Dev - Remove SkyVerge framework. PR#690 PR#689 PR#688 PR#687 PR#684 PR#683 PR#681 PR#678
|
14 |
+
|
15 |
+
= 2.9.1 - 2022-03-17 =
|
16 |
+
* Fix - Fatal error while deactivating WooCommerce before WooCommerce Square.
|
17 |
+
|
18 |
+
= 2.9.0 - 2022-02-17 =
|
19 |
+
* New - Added admin notice about v3 major update. PR#707
|
20 |
+
* Fix - Trim spaces from postal code at prefix and suffix positions. PR#654
|
21 |
+
|
22 |
+
= 2.8.0 - 2022-01-24 =
|
23 |
+
* New - Add support for Square stores located in Spain. PR#704
|
24 |
+
|
25 |
+
= 2.7.0 - 2021-11-09 =
|
26 |
+
* New - `wc_square_beta_country_support_spain` filter to add Spain as a supported country. PR#663
|
27 |
+
* Fix - Visibility of digital wallet buttons based on account & privacy settings. PR#652
|
28 |
+
|
29 |
+
= 2.6.0 - 2021-09-29 =
|
30 |
+
* New - Add support for Square stores located in France. PR#650
|
31 |
+
* Fix - PHP warning when trying to load the Square digital wallet (Apple/Google Pay buttons) on a product page that isn't available for purchase. PR#640
|
32 |
+
|
33 |
+
= 2.5.3 - 2021-07-23 =
|
34 |
+
* Fix - Failed orders with error "Square Payment Failed (Status code VALUE_TOO_LOW)" caused by incorrect line item calculations on orders with discounts/coupons (introduced in 2.5.2). PR#635
|
35 |
+
|
36 |
+
= 2.5.2 - 2021-07-21 =
|
37 |
+
* Fix - Product and inventory data not being synced due to duplicate/orphaned product metadata in database. PR#625
|
38 |
+
* Fix - Bypass SSL verification when checking background job processing eligibility. PR#624
|
39 |
+
* Fix - Correctly apply taxes in the Order API request and report accurate percentages. PR#559
|
40 |
+
|
41 |
+
= 2.5.1 - 2021-05-18 =
|
42 |
+
* Fix - Pay for Order and Add Payment Method forms sometimes not working when choosing another payment method other than Square. PR#618
|
43 |
+
|
44 |
+
= 2.5.0 - 2021-05-13 =
|
45 |
+
* New - Add support for WooCommerce Checkout blocks. PR#604
|
46 |
+
* New - Add support for Square stores located in Ireland. PR#609
|
47 |
+
* Fix - Improve manual sync performance and reduce stream timeout responses from Square on stores with large catalogs. PR#612
|
48 |
+
|
49 |
+
= 2.4.1 - 2021-03-30 =
|
50 |
+
* Fix - Variable products are now properly importing from Square on newer versions of WooCommerce. PR#605
|
51 |
+
|
52 |
+
= 2.4.0 - 2021-03-23 =
|
53 |
+
* Fix - Update jQuery 3 deprecated functions. PR#560
|
54 |
+
* Fix - Don't display digital wallet buttons when the cart contains a subscription product as Square does not yet support tokenization through digital wallets. PR#597
|
55 |
+
* Dev - Replace CoffeeScript with plain JS. PR#560
|
56 |
+
|
57 |
+
= 2.3.4 - 2021-02-11 =
|
58 |
+
* Fix - Handle exceptions when loading digital wallet buttons on product pages with no stock or other serviceable issues. PR#591
|
59 |
+
|
60 |
+
= 2.3.3 - 2021-02-09 =
|
61 |
+
* Fix - Uncaught PHP error when attempting to setup Apple Pay and Square is not properly connected (i.e. no valid access token found). PR#587
|
62 |
+
* Fix - Improve error logging when the request to verify the store's domain with Square/Apple Pay fails. PR#587
|
63 |
+
* Fix - Allow variable products to be previewed when Square is active. PR#554
|
64 |
+
|
65 |
+
= 2.3.2 - 2021-02-04 =
|
66 |
+
* Fix - PHP error on the My Account > Payment Methods page when saving a new card. PR#585
|
67 |
+
|
68 |
+
= 2.3.1 - 2021-02-03 =
|
69 |
+
* Fix - Add the correct variation to the cart when purchasing with Apple Pay and Google Pay from the product page. PR#581
|
70 |
+
|
71 |
+
= 2.3.0 - 2021-02-02 =
|
72 |
+
* Feature - Apple Pay and Google Pay support (US, UK and CA stores only). PR#547
|
73 |
+
* Fix - Duplicate `idempotency_key` issues caused by order IDs being re-used on the same store URL (i.e. after restoring from a backup). PR#563
|
74 |
+
* Fix - Don't import item variations from Square that are not available at your store's business location. PR#562
|
75 |
+
* Fix - Restore stock in Square when processing partial refunds (previously was only restoring stock for full refunds). PR#565
|
76 |
+
* Fix - Only restore stock if the "Restock refunded items" option is checked when refunding an order. PR#565
|
77 |
+
* Fix - Fatal errors during the sync and import process caused by unexpected/invalid Square API responses. PR#500
|
78 |
+
* Fix - Sends only one sync complete email per update to products that are synced with Square. PR#552
|
79 |
+
* Fix - Allow products with large numbers of categories (600+) to sync to Square when WooCommerce is SOR. PR#568
|
80 |
+
* Fix - Database related errors with creating the Square customer's table when first installing Square. PR#558
|
81 |
+
* Fix - Allow variable products with valid variations to import when variations with missing skus are present. PR#573
|
82 |
+
* Tweak - Update the Customer Profile setting description to make it clear that this setting enables tokenization. PR#576
|
83 |
+
|
84 |
+
= 2.2.5 - 2020-11-24 =
|
85 |
+
* Fix - Correctly saves inventory sync time when sync fails so items are re-synced on next attempt. PR#448
|
86 |
+
* Fix - Fixes warnings introduced with PHP 8. PR#533
|
87 |
+
* Fix - Corrects the plugin support URL. PR#539
|
88 |
+
* Fix - Allows imports containing products with variable pricing to complete successfully. PR#540
|
89 |
+
* Tweak - Updates assets to reflect WooCommerce color change. PR#544
|
90 |
+
|
91 |
+
= 2.2.4 - 2020-10-30 =
|
92 |
+
* Fix - Prevents logging anything if logging is disabled. PR#493
|
93 |
+
* Fix - Fixes a bug where products are imported even when it is not available at the store's location. PR#537
|
94 |
+
|
95 |
+
= 2.2.3 - 2020-10-23 =
|
96 |
+
* Fix - Display the correct stock quantity amount on all variations when product data is sent to Square. PR#503
|
97 |
+
* Fix - Avoid IDEMPOTENCY_KEY_REUSED API errors when syncing product data from WooCommerce to Square by using a more unique API request key. PR#528
|
98 |
+
* Fix - Added customer_id to Orders API to link Customers & Transactions on Square Dashboard and Transactions CSV Export. PR#527
|
99 |
+
* Fix - Issues with the postal code not matching WooCommerce data while saving cards. PR#501
|
100 |
+
* Fix - Prevents the "Send product data to Square" checkbox from being enabled when products and variations contain empty or duplicate SKUs. PR#525
|
101 |
+
* Fix - Issues that caused the Square Payment Form to be unclickable on the checkout page. PR#530
|
102 |
+
* Fix - Compatibility issues with the Square Payment form and conditional payment gateway extensions. PR#530
|
103 |
+
|
104 |
+
= 2.2.2 - 2020-09-15 =
|
105 |
+
* Fix - Don't import a new copy of each product image from Square when updating products during the import process. PR#513
|
106 |
+
|
107 |
+
= 2.2.1 - 2020-09-11 =
|
108 |
+
* New - Make the "Update existing products" part of the new import process optional by adding a new checkbox on Import Products modal. PR#508
|
109 |
+
* Fix - Stop the import process from getting stuck in a loop when reaching the time limit. PR#511
|
110 |
+
* Fix - Don't import/update categories from Square that are attached to products that cannot be found in WooCommerce. PR#511
|
111 |
+
* Fix - "idempotency_key must not be greater than 45 length" errors returned by some payment requests on stores using custom order number plugins. PR#507
|
112 |
+
|
113 |
+
= 2.2.0 - 2020-08-31 =
|
114 |
+
* Feature - Import new product variations from square to existing products in WooCommerce. PR#475
|
115 |
+
* Feature - Variations that are removed from Square will now be removed from products in WooCommerce during import. PR#475
|
116 |
+
* Feature - Upgrade to the Square Payments and Refunds API. PR#408
|
117 |
+
* Feature - New orders can be refunded up to one year after payment (up from 120 days). PR#408
|
118 |
+
* Fix - Only import products from Square that have non-empty SKUs. PR#475
|
119 |
+
* Fix - Empty product categories imported from Square into WooCommerce. PR#475
|
120 |
+
* Fix - Assign existing products to new categories imported from Square. PR#475
|
121 |
+
* Fix - Prevents loading of Square Assets on all pages except My Account -> Payment Methods & Checkout. PR#469
|
122 |
+
* Fix - Square Product Import & Product Manual Sync not triggering on mobile browsers. PR#472
|
123 |
+
* Fix - 3D Secure Verification Token is missing, Intent mismatch and other checkout errors related to SCA for merchants outside of the EU. PR#471
|
124 |
+
* Fix - Updated some of our documentation and support links in admin notices so they no longer redirect to an old URL or a 404 page. PR#474
|
125 |
+
* Fix - Use pagination to fetch inventory counts from Square. PR#478
|
126 |
+
* Fix - Display WooCommerce checkout validation errors along with Square payment form errors. PR#476
|
127 |
+
* Fix - Switching between sandbox and production environments will now show correct business locations. PR#462
|
128 |
+
* Fix - Don't wipe a customer's saved cards on when we receive an API error. PR#460
|
129 |
+
* Fix - Exclude draft and pending products from syncing from WooCommerce to Square. PR#484
|
130 |
+
* Fix - DevTools errors caused by missing minified JS files.
|
131 |
+
* Fix - PHP errors when syncing large amounts of products (`get_data() on null` and `getCursor() on a string`). PR#497
|
132 |
+
|
133 |
+
= 2.1.6 - 2020-07-15 =
|
134 |
+
* Fix - Make the "Sync Now" button disabled when no business location is set in Square settings.
|
135 |
+
* Fix - Enable checking/unchecking the Manage Stock setting for all variations.
|
136 |
+
* Fix - Refunding an order paid with another payment gateway will no longer sync inventory with Square when "Do not sync product data" is selected.
|
137 |
+
* Fix - Imported variation products that are out-of-stock will no longer show on the shop page when "Hide out of stock items from the catalog" is selected.
|
138 |
+
* Fix - Product images will now sync when Square is in Sandbox mode.
|
139 |
+
* Fix - Damaged stock adjustments will now sync properly to WooCommerce when multiple stock adjustments are made.
|
140 |
+
* Fix - Improve performance when manually syncing large amount of stock adjustments from Square (some inventory updates were missing).
|
141 |
+
* Fix - Quick editing products no longer sets incorrect stock quantities or disables syncing.
|
142 |
+
* Fix - Existing customer that have been removed from the connected Square account, or can't be found will now be able to save a new card on the checkout.
|
143 |
+
* Fix - When the System of Record is set to WooCommerce, product images will now properly sync to Square.
|
144 |
+
* Tweak - Use CSC consistently in all error messages when referring to the Card Security Code.
|
145 |
+
* Tweak - Change to using WordPress core methods to import/sync images from Square.
|
146 |
+
|
147 |
+
= 2.1.5 - 2020-05-15 =
|
148 |
+
* Fix - Fatal errors caused by incorrectly fetching locations before plugin init.
|
149 |
+
* Fix - WordPress database error when creating the Square Customers table on servers using utf8mb4.
|
150 |
+
|
151 |
+
= 2.1.4 - 2020-05-05 =
|
152 |
+
* Fix - Make sure that Square credit card fields are editable after checkout form refresh.
|
153 |
+
|
154 |
+
= 2.1.3 - 2020-04-30 =
|
155 |
+
* Fix - Persistent caching of locations to prevent unnecessary refetching and rate limiting.
|
156 |
+
|
157 |
+
= 2.1.2 - 2020-04-29 =
|
158 |
+
* Fix - INTENT_MISMATCH errors when guest customers save a card and registration is disabled.
|
159 |
+
* Fix - Improve checkout compatibility with password managers such as 1Password. This also avoids payment for reload on address change.
|
160 |
+
* Fix - Pass valid address values even if checkout fields are not present.
|
161 |
+
* Tweak - Sandbox mode can be turned on in the settings, no more need for setting the constant.
|
162 |
+
* Tweak - Change location URL to refer to our docs.
|
163 |
+
|
164 |
+
= 2.1.1 - 2020-03-23 =
|
165 |
+
* Fix - Inventory/Stock updates as a result of checkout via PayPal Standard does not reflect on the Square item.
|
166 |
+
* Fix - Error when trying to save an external product with the modified 'sync with square' value.
|
167 |
+
* Fix - Move product check on a possibly invalid product out of the try block avoiding potential further errors.
|
168 |
+
|
169 |
+
= 2.1.0 - 2020-02-11 =
|
170 |
+
* Feature - Add support for SCA (3D Secure 2)
|
171 |
+
* Fix - Minor fixes to the Sync completed emails
|
172 |
+
* Tweak - Add email notifications when connection issues are detected
|
173 |
+
* Fix - Category sync when WooCommerce is the System of Record and there have been changes in Square
|
174 |
+
|
175 |
+
= 2.0.8 - 2019-12-09 =
|
176 |
+
* Fix - Inventory changes through payments and refunds from other gateways not reflected on Square.
|
177 |
+
* Fix - Fatal error on versions of WooCommerce before 4.3.
|
178 |
+
* Fix - Sandbox API calls by passing is_sandbox flag to the Gateway API.
|
179 |
+
* Fix - Quick edit view when editing a variable product without all variations SKU.
|
180 |
+
* Fix - Verify if the product can be synced with Square before enabling sync when bulk/quick updating.
|
181 |
+
* Fix - Disable sync for products that should not be synced after a REST API update.
|
182 |
+
* Fix - Unable to create products during import.
|
183 |
+
* Fix - Product inventory sync issue when WooCommerce is set as the Source of Record.
|
184 |
+
* Fix - Inventory not updated when purchased through another gateway.
|
185 |
+
* Fix - Category and description data not updated in a sync from Square.
|
186 |
+
* Fix - Transactions on multiple stores connected to the same Square account would appear to succeed without actually charging the customer.
|
187 |
+
* Fix - When making multiple partial refunds on the same order, only the first one would work.
|
188 |
+
* Tweak - Include product ID on failed sync record message.
|
189 |
+
* Tweak - Remove notices for refresh token when sandbox is enabled.
|
190 |
+
* Tweak - Prevent refreshing a token token when sandbox is enabled.
|
191 |
+
|
192 |
+
= 2.0.7 - 2019-11-18 =
|
193 |
+
* Fix - No longer automatically disconnect on unexpected authorization errors
|
194 |
+
* Fix - Bump compatibility for WooCommerce 3.8 and WordPress 5.3
|
195 |
+
* Fix - Correct cents rounding that was causing invalid value errors
|
196 |
+
* Fix - Fix encrypted token handling
|
197 |
+
* Fix - No longer call revoke when disconnecting - just disconnect the site
|
198 |
+
|
199 |
+
= 2.0.6 - 2019-11-07 =
|
200 |
+
* Fix - Access token renewal schedule action duplication.
|
201 |
+
|
202 |
+
= 2.0.5 - 2019-10-16 =
|
203 |
+
* Fix - Access token renewal by adding support for refresh tokens as per the new Square API
|
204 |
+
* Fix - Variable pricing import and adding an alert when these type of products are ignored.
|
205 |
+
* Fix - Line item discounts and other adjustments being ignored.
|
206 |
+
* Tweak - Add a notice when a refresh token is not present to warn users to re-connect their accounts.
|
207 |
+
* Feature - Added support for Sandbox accounts.
|
208 |
+
|
209 |
+
= 2.0.4 - 2019-09-03 =
|
210 |
+
* Fix - Add adjustments to Square order in the event of discrepancy with WooCommerce total
|
211 |
+
|
212 |
+
= 2.0.3 - 2019-08-19 =
|
213 |
+
* Tweak - Re-introduce the "inventory sync" toggle to allow syncing product data without affecting inventory
|
214 |
+
* Fix - Adjust v1 upgrades to properly toggle inventory sync when not enabled in v1
|
215 |
+
* Fix - Ensure product prices are correctly converted to and from cents regardless of the decimal place setting
|
216 |
+
* Fix - Don't block the product stock management UI when product sync is disabled
|
217 |
+
* Fix - Ensure products that have multiple attributes that aren't used for variations can be synced
|
218 |
+
* Misc - Add support for WooCommerce 3.7
|
219 |
+
|
220 |
+
= 2.0.2 - 2019-08-13 =
|
221 |
+
* Tweak – WC 3.7 compatibility.
|
222 |
+
|
223 |
+
= 2.0.1 - 2019-07-23 =
|
224 |
+
* Fix - Don't display the "unsupported" payment processing admin notice for UK-based merchants
|
225 |
+
|
226 |
+
= 2.0.0 - 2019-07-22 =
|
227 |
+
* Feature - Support Square customer profiles for saved payment methods
|
228 |
+
* Feature - Customers can label their saved payment methods for easy identification when choosing how to pay
|
229 |
+
* Feature - Support enhanced payment form with auto formatting and retina card icons
|
230 |
+
* Feature - Show detailed decline messages when possible in place of generic errors
|
231 |
+
* Feature - Add support for WooCommerce Subscriptions
|
232 |
+
* Feature - Add support for WooCommerce Pre-Orders
|
233 |
+
* Feature - Orders with only virtual items can force a charge instead of authorization
|
234 |
+
* Feature - Void authorizations from WooCommerce
|
235 |
+
* Feature - Itemize Square transactions for improved reporting in Square
|
236 |
+
* Feature - Add sync records to notify admins of failed product syncs
|
237 |
+
* Feature - Changed "Synced with Square" option while bulk editing products
|
238 |
+
* Tweak - Introduce "System of Record" settings to control product data sync
|
239 |
+
* Tweak - Remove items from Square locations when deleted in WooCommerce (if WC is the system of record)
|
240 |
+
* Tweak - Allow users to hide WooCommerce products if removed from the linked Square location (if Square is the system of record)
|
241 |
+
* Tweak - Import images from Square when not set in WooCommerce (if Square is the system of record)
|
242 |
+
* Tweak - Remove Square postcode field when a postcode can be used from the checkout form
|
243 |
+
* Fix - Ensure connection tokens are refreshed ahead of expiration
|
244 |
+
* Fix - Always ensure settings are displayed in multisite
|
245 |
+
* Fix - Ensure Square prices update WooCommerce regular price, not sale price
|
246 |
+
* Fix - Remove usages of `$HTTP_RAW_POST_DATA`, which is deprecated
|
247 |
+
* Fix - Do not allow multiple sync processes to run simultaneously
|
248 |
+
* Fix - Avoid submitting duplicate orders with Checkout for WC plugin
|
249 |
+
* Misc - Upgrade to Square Connect v2 APIs
|
250 |
+
* Misc - Background process product sync for improved scalability
|
251 |
+
* Misc - Refactor for other miscellaneous fixes and improved reliability
|
252 |
+
|
253 |
+
= 1.0.38 - 2019-07-05 =
|
254 |
+
* Fix - Re-deploy due to erroneous inclusion of trunk folder
|
255 |
+
|
256 |
+
= 1.0.37 – 2019-04-16 =
|
257 |
+
* Fix – Use correct assets loading scheme.
|
258 |
+
|
259 |
+
= 1.0.36 – 2019-04-15 =
|
260 |
+
* Tweak – WC 3.6 compatibility.
|
261 |
+
|
262 |
+
= 1.0.35 - 2019-02-01 =
|
263 |
+
* Fix - Idempotency key reuse issue when checking out.
|
264 |
+
|
265 |
+
= 1.0.34 - 2018-11-07 =
|
266 |
+
* Update - Fieldset tag to div tag in payment box to prevent unwanted styling.
|
267 |
+
* Fix - Provide unique idempotency ID to the order instead of random unique number.
|
268 |
+
* Update - WP tested up to version 5.0
|
269 |
+
|
270 |
+
= 1.0.33 - 2018-09-27 =
|
271 |
+
* Update - WC tested up to version 3.5
|
272 |
+
|
273 |
+
= 1.0.32 - 2018-08-23 =
|
274 |
+
* Fix - UK/GB localed does not support Diners/Discover, so do not show these brands on checkout.
|
275 |
+
|
276 |
+
= 1.0.25 =
|
277 |
+
* Public Release!
|
composer.json
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "woocommerce/woocommerce-square",
|
3 |
-
"description": "WooCommerce Square",
|
4 |
-
"homepage": "https://woocommerce.com/products/woocommerce-square/",
|
5 |
-
"license": "GPL 3.0",
|
6 |
-
"minimum-stability": "dev",
|
7 |
-
"repositories": [
|
8 |
-
{
|
9 |
-
"type": "vcs",
|
10 |
-
"url": "https://github.com/skyverge/wc-plugin-framework"
|
11 |
-
}
|
12 |
-
],
|
13 |
-
"require": {
|
14 |
-
"square/connect": "2.20190814.2",
|
15 |
-
"skyverge/wc-plugin-framework": "5.4.0",
|
16 |
-
"prospress/action-scheduler" : "2.2.0"
|
17 |
-
},
|
18 |
-
"require-dev": {
|
19 |
-
"woocommerce/woocommerce-sniffs": "0.1.0"
|
20 |
-
},
|
21 |
-
"scripts": {
|
22 |
-
"phpcs": [
|
23 |
-
"vendor/bin/phpcs"
|
24 |
-
]
|
25 |
-
}
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
i18n/languages/woocommerce-square.pot
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
# This file is distributed under the GNU General Public License v3.0.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WooCommerce Square
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://wordpress.org/support/plugin/woocommerce-square\n"
|
8 |
-
"POT-Creation-Date: 2022-
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -14,70 +14,70 @@ msgstr ""
|
|
14 |
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
|
15 |
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
16 |
|
17 |
-
#: includes/AJAX.php:
|
18 |
msgid "Please mark product as un-synced and save, then synced again."
|
19 |
msgstr ""
|
20 |
|
21 |
-
#: includes/AJAX.php:
|
22 |
#. translators: Placeholders: %1$s = error message, %2$s = help text
|
23 |
msgid "Unable to fetch inventory: %1$s. %2$s"
|
24 |
msgstr ""
|
25 |
|
26 |
-
#: includes/AJAX.php:
|
27 |
#. translators: Placeholders: %s = help text
|
28 |
msgid "Error finding item in Square. %s"
|
29 |
msgstr ""
|
30 |
|
31 |
-
#: includes/AJAX.php:
|
32 |
msgid "Could not start import. Please try again."
|
33 |
msgstr ""
|
34 |
|
35 |
-
#: includes/AJAX.php:
|
36 |
msgid ""
|
37 |
"Your products are being imported in the background! This may take some time "
|
38 |
"to complete."
|
39 |
msgstr ""
|
40 |
|
41 |
-
#: includes/AJAX.php:
|
42 |
msgid "Could not delete records."
|
43 |
msgstr ""
|
44 |
|
45 |
-
#: includes/AJAX.php:
|
46 |
msgid "Could not delete record."
|
47 |
msgstr ""
|
48 |
|
49 |
-
#: includes/AJAX.php:
|
50 |
msgid "Could not resolve record."
|
51 |
msgstr ""
|
52 |
|
53 |
-
#: includes/AJAX.php:
|
54 |
msgid "Could not unsync product."
|
55 |
msgstr ""
|
56 |
|
57 |
-
#: includes/AJAX.php:
|
58 |
#. translators: Placeholder: %s - error message
|
59 |
msgid "An error occurred. %s"
|
60 |
msgstr ""
|
61 |
|
62 |
-
#: includes/AJAX.php:
|
63 |
#. translators: Placeholder: %s - sync job ID
|
64 |
msgid "No sync job in progress found %s"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: includes/AJAX.php:
|
68 |
msgid "Stock must be fetched from Square before editing stock quantity"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: includes/Admin/Privacy.php:
|
72 |
-
#: includes/Gateway.php:
|
73 |
msgid "Square"
|
74 |
msgstr ""
|
75 |
|
76 |
-
#: includes/Admin/Privacy.php:
|
77 |
msgid "WooCommerce Square Customer Data"
|
78 |
msgstr ""
|
79 |
|
80 |
-
#: includes/Admin/Privacy.php:
|
81 |
#. translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag
|
82 |
msgid ""
|
83 |
"By using this extension, you may be storing personal data or sharing data "
|
@@ -85,27 +85,27 @@ msgid ""
|
|
85 |
"what you may want to include in your privacy policy.%2$s"
|
86 |
msgstr ""
|
87 |
|
88 |
-
#: includes/Admin/Privacy.php:
|
89 |
msgid "Square User Data Erased."
|
90 |
msgstr ""
|
91 |
|
92 |
-
#: includes/Admin/Settings_Page.php:
|
93 |
msgid "Settings"
|
94 |
msgstr ""
|
95 |
|
96 |
-
#: includes/Admin/Settings_Page.php:
|
97 |
msgid "Update"
|
98 |
msgstr ""
|
99 |
|
100 |
-
#: includes/Admin/Settings_Page.php:
|
101 |
msgid "Import Products From Square"
|
102 |
msgstr ""
|
103 |
|
104 |
-
#: includes/Admin/Settings_Page.php:
|
105 |
msgid "Close modal window"
|
106 |
msgstr ""
|
107 |
|
108 |
-
#: includes/Admin/Settings_Page.php:
|
109 |
#. translators: Placeholders: %1$s - <strong>, %2%s - </strong>
|
110 |
msgid ""
|
111 |
"You are about to import all new products, variations and categories from "
|
@@ -114,11 +114,11 @@ msgid ""
|
|
114 |
"imports, these will be ignored in the import."
|
115 |
msgstr ""
|
116 |
|
117 |
-
#: includes/Admin/Settings_Page.php:
|
118 |
msgid "Do you wish to import existing product updates from Square?"
|
119 |
msgstr ""
|
120 |
|
121 |
-
#: includes/Admin/Settings_Page.php:
|
122 |
#. translators: Placeholders: %1$s - <a> tag linking to WooCommerce Square
|
123 |
#. docs, %2%s - closing </a> tag
|
124 |
msgid ""
|
@@ -126,26 +126,26 @@ msgid ""
|
|
126 |
"information from Square. %1$sView Documentation%2$s."
|
127 |
msgstr ""
|
128 |
|
129 |
-
#: includes/Admin/Settings_Page.php:
|
130 |
msgid "Update existing products during import."
|
131 |
msgstr ""
|
132 |
|
133 |
-
#: includes/Admin/Settings_Page.php:
|
134 |
-
#:
|
135 |
-
#:
|
136 |
-
#: vendor/
|
137 |
msgid "Cancel"
|
138 |
msgstr ""
|
139 |
|
140 |
-
#: includes/Admin/Settings_Page.php:
|
141 |
msgid "Import Products"
|
142 |
msgstr ""
|
143 |
|
144 |
-
#: includes/Admin/Sync_Page.php:
|
145 |
msgid "Sync records"
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: includes/Admin/Sync_Page.php:
|
149 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
150 |
#. $4%s - closing </strong> HTML tag
|
151 |
msgid ""
|
@@ -154,7 +154,7 @@ msgid ""
|
|
154 |
"description, category, inventory%4$s."
|
155 |
msgstr ""
|
156 |
|
157 |
-
#: includes/Admin/Sync_Page.php:
|
158 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
159 |
#. </strong> HTML tag
|
160 |
msgid ""
|
@@ -162,7 +162,7 @@ msgid ""
|
|
162 |
"set in WooCommerce."
|
163 |
msgstr ""
|
164 |
|
165 |
-
#: includes/Admin/Sync_Page.php:
|
166 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
167 |
#. %4$s - closing </strong> HTML tag
|
168 |
msgid ""
|
@@ -171,7 +171,7 @@ msgid ""
|
|
171 |
"price, inventory, category, image%4$s."
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: includes/Admin/Sync_Page.php:
|
175 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
176 |
#. </strong> HTML tag
|
177 |
msgid ""
|
@@ -179,46 +179,46 @@ msgid ""
|
|
179 |
"Square and WooCommerce."
|
180 |
msgstr ""
|
181 |
|
182 |
-
#: includes/Admin/Sync_Page.php:
|
183 |
msgid "Please connect to Square to enable product sync."
|
184 |
msgstr ""
|
185 |
|
186 |
-
#: includes/Admin/Sync_Page.php:
|
187 |
msgid "Please set the business location to enable product sync."
|
188 |
msgstr ""
|
189 |
|
190 |
-
#: includes/Admin/Sync_Page.php:
|
191 |
msgid "There are currently no products marked to be synced with Square."
|
192 |
msgstr ""
|
193 |
|
194 |
-
#: includes/Admin/Sync_Page.php:
|
195 |
msgid "A sync is currently in progress. Please try again later."
|
196 |
msgstr ""
|
197 |
|
198 |
-
#: includes/Admin/Sync_Page.php:
|
199 |
#. translators: Placeholder: %s - reason text
|
200 |
msgid "Product sync between WooCommerce and Square is currently unavailable. %s"
|
201 |
msgstr ""
|
202 |
|
203 |
-
#: includes/Admin/Sync_Page.php:
|
204 |
msgid "Synced products"
|
205 |
msgstr ""
|
206 |
|
207 |
-
#: includes/Admin/Sync_Page.php:
|
208 |
msgid "Latest sync"
|
209 |
msgstr ""
|
210 |
|
211 |
-
#: includes/Admin/Sync_Page.php:
|
212 |
msgid "Next sync"
|
213 |
msgstr ""
|
214 |
|
215 |
-
#: includes/Admin/Sync_Page.php:
|
216 |
-
#: includes/Admin/Sync_Page.php:
|
217 |
-
#:
|
218 |
msgid "Actions"
|
219 |
msgstr ""
|
220 |
|
221 |
-
#: includes/Admin/Sync_Page.php:
|
222 |
#. translators: Placeholder: %d number of products synced with Square
|
223 |
#. translators: Placeholder: %d products count
|
224 |
msgid "%d product"
|
@@ -226,66 +226,67 @@ msgid_plural "%d products"
|
|
226 |
msgstr[0] ""
|
227 |
msgstr[1] ""
|
228 |
|
229 |
-
#: includes/Admin/Sync_Page.php:
|
230 |
msgid "Importing now…"
|
231 |
msgstr ""
|
232 |
|
233 |
-
#: includes/Admin/Sync_Page.php:
|
234 |
msgid "Syncing now…"
|
235 |
msgstr ""
|
236 |
|
237 |
-
#: includes/Admin/Sync_Page.php:
|
238 |
msgid "Not synced yet."
|
239 |
msgstr ""
|
240 |
|
241 |
-
#: includes/Admin/Sync_Page.php:
|
242 |
msgid "Sync now"
|
243 |
msgstr ""
|
244 |
|
245 |
-
#: includes/Admin/Sync_Page.php:
|
246 |
-
#: vendor/
|
|
|
247 |
msgid "Status"
|
248 |
msgstr ""
|
249 |
|
250 |
-
#: includes/Admin/Sync_Page.php:
|
251 |
msgid "Message"
|
252 |
msgstr ""
|
253 |
|
254 |
-
#: includes/Admin/Sync_Page.php:
|
255 |
msgid "No records found."
|
256 |
msgstr ""
|
257 |
|
258 |
-
#: includes/Admin/Sync_Page.php:
|
259 |
msgid "Sync products with Square"
|
260 |
msgstr ""
|
261 |
|
262 |
-
#: includes/Admin/Sync_Page.php:
|
263 |
msgid ""
|
264 |
"If a match is found in Square, product data in WooCommerce will be "
|
265 |
"overwritten with Square data."
|
266 |
msgstr ""
|
267 |
|
268 |
-
#: includes/Admin/Sync_Page.php:
|
269 |
msgid ""
|
270 |
"If a match is found in WooCommerce, product data in Square will be "
|
271 |
"overwritten with WooCommerce data."
|
272 |
msgstr ""
|
273 |
|
274 |
-
#: includes/Admin/Sync_Page.php:
|
275 |
msgid ""
|
276 |
"If a match is not found in Square, the product will be hidden from the "
|
277 |
"catalog in WooCommerce."
|
278 |
msgstr ""
|
279 |
|
280 |
-
#: includes/Admin/Sync_Page.php:
|
281 |
msgid "If a match is not found in Square, the product will be skipped in the sync."
|
282 |
msgstr ""
|
283 |
|
284 |
-
#: includes/Admin/Sync_Page.php:
|
285 |
msgid "If a match is not found, a new product will be created in Square."
|
286 |
msgstr ""
|
287 |
|
288 |
-
#: includes/Admin/Sync_Page.php:
|
289 |
#. translators: Placeholders: %1$s - the system of record name (e.g. Square or
|
290 |
#. WooCommerce), %3%s - unordered HTML list of additional information item(s)
|
291 |
msgid ""
|
@@ -293,11 +294,11 @@ msgid ""
|
|
293 |
"For all products synced with Square: %2$s"
|
294 |
msgstr ""
|
295 |
|
296 |
-
#: includes/Admin/Sync_Page.php:
|
297 |
msgid "Start sync"
|
298 |
msgstr ""
|
299 |
|
300 |
-
#: includes/Admin.php:143 includes/Handlers/Products.php:
|
301 |
msgid "Synced with Square"
|
302 |
msgstr ""
|
303 |
|
@@ -309,54 +310,54 @@ msgstr ""
|
|
309 |
msgid "Fetch stock from Square"
|
310 |
msgstr ""
|
311 |
|
312 |
-
#: includes/Admin.php:
|
313 |
msgid "Resolved"
|
314 |
msgstr ""
|
315 |
|
316 |
-
#: includes/Admin.php:
|
317 |
msgid "No records found"
|
318 |
msgstr ""
|
319 |
|
320 |
-
#: includes/Admin.php:
|
321 |
msgid "Skipped"
|
322 |
msgstr ""
|
323 |
|
324 |
-
#: includes/Admin.php:
|
325 |
msgid "Updated"
|
326 |
msgstr ""
|
327 |
|
328 |
-
#: includes/Admin.php:
|
329 |
msgid "Imported"
|
330 |
msgstr ""
|
331 |
|
332 |
-
#: includes/Admin.php:
|
333 |
msgid "Enable to fetch inventory changes from Square"
|
334 |
msgstr ""
|
335 |
|
336 |
-
#: includes/Admin.php:
|
337 |
msgid "Enable to push inventory changes to Square"
|
338 |
msgstr ""
|
339 |
|
340 |
-
#: includes/Admin.php:
|
341 |
msgid "Inventory is fetched from Square periodically and updated in WooCommerce"
|
342 |
msgstr ""
|
343 |
|
344 |
-
#: includes/Admin.php:
|
345 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
346 |
msgid ""
|
347 |
"Inventory is %1$salways fetched from Square%2$s periodically to account for "
|
348 |
"sales from other channels."
|
349 |
msgstr ""
|
350 |
|
351 |
-
#: includes/Emails/Access_Token_Email.php:
|
352 |
msgid "Square Access Token problems"
|
353 |
msgstr ""
|
354 |
|
355 |
-
#: includes/Emails/Access_Token_Email.php:
|
356 |
msgid "This email is sent when problems with Access Token are encountered"
|
357 |
msgstr ""
|
358 |
|
359 |
-
#: includes/Emails/Access_Token_Email.php:
|
360 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
361 |
#. </a> HTML link tag
|
362 |
msgid ""
|
@@ -364,14 +365,14 @@ msgid ""
|
|
364 |
"re-connect your site%2$s."
|
365 |
msgstr ""
|
366 |
|
367 |
-
#: includes/Emails/Access_Token_Email.php:
|
368 |
-
#: includes/Emails/Sync_Completed.php:
|
369 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
370 |
#. </a> HTML link tag
|
371 |
msgid "%1$sInspect status logs%2$s"
|
372 |
msgstr ""
|
373 |
|
374 |
-
#: includes/Emails/Access_Token_Email.php:
|
375 |
msgid ""
|
376 |
"In order to continue accepting payments, please disconnect and re-connect "
|
377 |
"your site at "
|
@@ -394,1387 +395,1445 @@ msgid ""
|
|
394 |
"%s"
|
395 |
msgstr ""
|
396 |
|
397 |
-
#: includes/Emails/Sync_Completed.php:
|
398 |
msgid "Square sync completed"
|
399 |
msgstr ""
|
400 |
|
401 |
-
#: includes/Emails/Sync_Completed.php:
|
402 |
msgid ""
|
403 |
"This email is sent once a manual sync has been completed between "
|
404 |
"WooCommerce and Square"
|
405 |
msgstr ""
|
406 |
|
407 |
-
#: includes/Emails/Sync_Completed.php:
|
408 |
msgid "Square sync failed"
|
409 |
msgstr ""
|
410 |
|
411 |
-
#: includes/Emails/Sync_Completed.php:
|
412 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
413 |
#. </a> HTML link tag
|
414 |
msgid "%1$sEnable logging%2$s"
|
415 |
msgstr ""
|
416 |
|
417 |
-
#: includes/Emails/Sync_Completed.php:
|
418 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
419 |
#. </a> HTML link tag, %3$s - additional action
|
420 |
msgid "The sync job has failed. %1$sClick for more details%2$s, or %3$s."
|
421 |
msgstr ""
|
422 |
|
423 |
-
#: includes/Emails/Sync_Completed.php:
|
424 |
msgid "Inspect status logs"
|
425 |
msgstr ""
|
426 |
|
427 |
-
#: includes/Emails/Sync_Completed.php:
|
428 |
msgid "Enable Logging"
|
429 |
msgstr ""
|
430 |
|
431 |
-
#: includes/Emails/Sync_Completed.php:
|
432 |
#. translators: Placeholders: %s - additional action
|
433 |
msgid "The sync job has failed. Check sync records, or %s."
|
434 |
msgstr ""
|
435 |
|
436 |
-
#: includes/
|
437 |
-
|
438 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay.php:555
|
439 |
-
msgid "Discount"
|
440 |
msgstr ""
|
441 |
|
442 |
-
#: includes/
|
443 |
-
|
444 |
-
msgid "Adjustment"
|
445 |
msgstr ""
|
446 |
|
447 |
-
#: includes/
|
448 |
-
|
449 |
-
#: includes/Gateway/Payment_Form.php:240 includes/Gateway.php:245
|
450 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Hosted_Payment_Handler.php:216
|
451 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2758
|
452 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/integrations/class-sv-wc-payment-gateway-integration-subscriptions.php:376
|
453 |
-
msgid "An error occurred, please try again or try an alternate form of payment."
|
454 |
msgstr ""
|
455 |
|
456 |
-
#: includes/
|
457 |
-
|
458 |
-
msgid "Credit Card"
|
459 |
msgstr ""
|
460 |
|
461 |
-
#: includes/
|
462 |
-
|
463 |
-
#. %3$s - version number
|
464 |
-
msgid ""
|
465 |
-
"%1$sWarning!%2$s Some Square + Checkout Block features do not work with "
|
466 |
-
"your version of WooCommerce Blocks (%3$s). Please update to the latest "
|
467 |
-
"version of WooCommerce Blocks or WooCommerce to fix these issues."
|
468 |
msgstr ""
|
469 |
|
470 |
-
#: includes/
|
471 |
-
#.
|
472 |
-
#.
|
473 |
msgid ""
|
474 |
-
"
|
475 |
-
"
|
476 |
-
"
|
477 |
msgstr ""
|
478 |
|
479 |
-
#: includes/
|
480 |
-
|
481 |
-
#. expected location of apple pay verification file, %4$s: opening href tag
|
482 |
-
#. with link to Square documentation, %5$s: closing href tag
|
483 |
-
msgid ""
|
484 |
-
"Apple Pay is not available with Square - there was a problem with "
|
485 |
-
"registering your store domain with Square/Apple Pay. %1$sView the Square "
|
486 |
-
"logs%2$s to find out what caused the registration to fail."
|
487 |
msgstr ""
|
488 |
|
489 |
-
#: includes/
|
490 |
-
msgid "
|
|
|
|
|
491 |
msgstr ""
|
492 |
|
493 |
-
#: includes/
|
494 |
-
|
495 |
-
msgid "
|
496 |
msgstr ""
|
497 |
|
498 |
-
#: includes/
|
499 |
-
|
500 |
-
msgid ""
|
501 |
-
"You cannot add that amount of \"%1$s\"; to the cart because there is not "
|
502 |
-
"enough stock (%2$s remaining)."
|
503 |
msgstr ""
|
504 |
|
505 |
-
#: includes/
|
506 |
-
|
507 |
-
msgid "You cannot purchase \"%1$s\" because it is currently not available."
|
508 |
msgstr ""
|
509 |
|
510 |
-
#: includes/
|
511 |
-
|
512 |
-
msgid "Tax"
|
513 |
msgstr ""
|
514 |
|
515 |
-
#: includes/
|
516 |
-
msgid "
|
517 |
msgstr ""
|
518 |
|
519 |
-
#: includes/
|
520 |
-
|
521 |
-
msgid "Pending"
|
522 |
msgstr ""
|
523 |
|
524 |
-
#: includes/
|
525 |
-
|
526 |
-
msgid "Shipping"
|
527 |
msgstr ""
|
528 |
|
529 |
-
#: includes/
|
530 |
-
#:
|
531 |
-
msgid "
|
532 |
msgstr ""
|
533 |
|
534 |
-
#: includes/
|
535 |
-
|
536 |
-
msgid "
|
537 |
msgstr ""
|
538 |
|
539 |
-
#: includes/
|
540 |
-
msgid "
|
541 |
msgstr ""
|
542 |
|
543 |
-
#: includes/
|
544 |
-
|
|
|
545 |
msgstr ""
|
546 |
|
547 |
-
#: includes/
|
548 |
-
|
|
|
|
|
549 |
msgstr ""
|
550 |
|
551 |
-
#: includes/
|
552 |
-
|
|
|
553 |
msgstr ""
|
554 |
|
555 |
-
#: includes/
|
556 |
-
msgid "
|
557 |
msgstr ""
|
558 |
|
559 |
-
#: includes/
|
560 |
-
msgid ""
|
561 |
-
"Could not find original transaction tender. Please refund this transaction "
|
562 |
-
"from your Square dashboard."
|
563 |
msgstr ""
|
564 |
|
565 |
-
#: includes/
|
566 |
-
#:
|
567 |
-
|
568 |
-
msgid "Enable / Disable"
|
569 |
msgstr ""
|
570 |
|
571 |
-
#: includes/
|
572 |
-
|
573 |
-
msgid "Enable this gateway"
|
574 |
msgstr ""
|
575 |
|
576 |
-
#: includes/
|
577 |
-
#:
|
578 |
-
|
|
|
|
|
579 |
msgstr ""
|
580 |
|
581 |
-
#: includes/
|
582 |
-
#:
|
583 |
-
msgid "
|
584 |
msgstr ""
|
585 |
|
586 |
-
#: includes/
|
587 |
-
|
588 |
-
msgid "Description"
|
589 |
msgstr ""
|
590 |
|
591 |
-
#: includes/
|
592 |
-
#:
|
593 |
-
|
|
|
594 |
msgstr ""
|
595 |
|
596 |
-
#: includes/
|
597 |
-
msgid "
|
598 |
msgstr ""
|
599 |
|
600 |
-
#: includes/
|
601 |
-
|
602 |
-
msgid "Detailed Decline Messages"
|
603 |
msgstr ""
|
604 |
|
605 |
-
#: includes/
|
606 |
-
|
607 |
-
msgid ""
|
608 |
-
"Check to enable detailed decline messages to the customer during checkout "
|
609 |
-
"when possible, rather than a generic decline message."
|
610 |
msgstr ""
|
611 |
|
612 |
-
#: includes/
|
613 |
-
#:
|
614 |
-
#:
|
615 |
msgid "Debug Mode"
|
616 |
msgstr ""
|
617 |
|
618 |
-
#: includes/
|
619 |
-
|
620 |
-
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
621 |
-
msgid ""
|
622 |
-
"Show Detailed Error Messages and API requests/responses on the checkout "
|
623 |
-
"page and/or save them to the %1$sdebug log%2$s"
|
624 |
msgstr ""
|
625 |
|
626 |
-
#: includes/
|
627 |
-
|
628 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:1203
|
629 |
-
msgid "Off"
|
630 |
msgstr ""
|
631 |
|
632 |
-
#: includes/
|
633 |
-
|
634 |
-
msgid "Show on Checkout Page"
|
635 |
msgstr ""
|
636 |
|
637 |
-
#: includes/
|
638 |
-
#:
|
639 |
-
#:
|
640 |
msgid "Save to Log"
|
641 |
msgstr ""
|
642 |
|
643 |
-
#: includes/
|
644 |
-
#:
|
645 |
-
|
646 |
-
msgid "
|
647 |
msgstr ""
|
648 |
|
649 |
-
#: includes/
|
650 |
-
msgid "
|
651 |
msgstr ""
|
652 |
|
653 |
-
#: includes/
|
654 |
-
msgid ""
|
655 |
-
"Check to enable tokenization and allow customers to securely save their "
|
656 |
-
"payment details for future checkout."
|
657 |
msgstr ""
|
658 |
|
659 |
-
#: includes/
|
660 |
-
msgid "
|
661 |
msgstr ""
|
662 |
|
663 |
-
#: includes/
|
664 |
-
msgid "
|
665 |
msgstr ""
|
666 |
|
667 |
-
#: includes/
|
668 |
-
|
669 |
-
msgid ""
|
670 |
-
"Allow customers to pay with Apple Pay or Google Pay from your Product, Cart "
|
671 |
-
"and Checkout pages. Read more about the availablity of digital wallets in "
|
672 |
-
"our %1$sdocumentation%2$s."
|
673 |
msgstr ""
|
674 |
|
675 |
-
#: includes/
|
676 |
-
msgid "
|
677 |
msgstr ""
|
678 |
|
679 |
-
#: includes/
|
680 |
-
msgid "
|
681 |
msgstr ""
|
682 |
|
683 |
-
#: includes/
|
684 |
-
msgid ""
|
685 |
-
"This setting only applies to the Apple Pay button. When Google Pay is "
|
686 |
-
"available, the Google Pay button will always have the \"Buy with\" button "
|
687 |
-
"text."
|
688 |
msgstr ""
|
689 |
|
690 |
-
#: includes/
|
691 |
-
msgid "
|
692 |
msgstr ""
|
693 |
|
694 |
-
#: includes/
|
695 |
-
|
|
|
696 |
msgstr ""
|
697 |
|
698 |
-
#: includes/
|
699 |
-
msgid "
|
|
|
|
|
|
|
700 |
msgstr ""
|
701 |
|
702 |
-
#: includes/
|
703 |
-
msgid "
|
|
|
|
|
704 |
msgstr ""
|
705 |
|
706 |
-
#: includes/
|
707 |
-
msgid "
|
|
|
|
|
708 |
msgstr ""
|
709 |
|
710 |
-
#: includes/
|
711 |
-
msgid "
|
712 |
msgstr ""
|
713 |
|
714 |
-
#: includes/
|
|
|
|
|
|
|
|
|
715 |
msgid ""
|
716 |
-
"
|
717 |
-
"
|
718 |
msgstr ""
|
719 |
|
720 |
-
#: includes/
|
721 |
-
|
|
|
|
|
|
|
722 |
msgstr ""
|
723 |
|
724 |
-
#: includes/
|
725 |
-
msgid "
|
726 |
msgstr ""
|
727 |
|
728 |
-
#: includes/
|
729 |
-
msgid "
|
730 |
msgstr ""
|
731 |
|
732 |
-
#: includes/
|
733 |
-
msgid "
|
734 |
msgstr ""
|
735 |
|
736 |
-
#: includes/
|
737 |
-
msgid "
|
738 |
msgstr ""
|
739 |
|
740 |
-
#: includes/
|
741 |
-
msgid "
|
742 |
msgstr ""
|
743 |
|
744 |
-
#: includes/
|
745 |
-
msgid "
|
746 |
msgstr ""
|
747 |
|
748 |
-
#: includes/
|
749 |
-
msgid "
|
750 |
msgstr ""
|
751 |
|
752 |
-
#: includes/
|
753 |
-
msgid "
|
754 |
msgstr ""
|
755 |
|
756 |
-
#: includes/
|
757 |
-
msgid "
|
758 |
msgstr ""
|
759 |
|
760 |
-
#: includes/
|
761 |
-
#. translators: Placeholder: %s category ID
|
762 |
msgid ""
|
763 |
-
"
|
764 |
-
"
|
765 |
msgstr ""
|
766 |
|
767 |
-
#: includes/
|
768 |
-
msgid "
|
|
|
|
|
769 |
msgstr ""
|
770 |
|
771 |
-
#: includes/
|
772 |
-
#. translators: Placeholder: %s - product name
|
773 |
msgid ""
|
774 |
-
"
|
775 |
-
"
|
776 |
msgstr ""
|
777 |
|
778 |
-
#: includes/
|
779 |
-
#. translators: Placeholder: %s - product name
|
780 |
msgid ""
|
781 |
-
"
|
782 |
-
"
|
783 |
-
"account."
|
784 |
msgstr ""
|
785 |
|
786 |
-
#: includes/
|
787 |
-
|
788 |
-
|
|
|
789 |
msgstr ""
|
790 |
|
791 |
-
#: includes/
|
792 |
-
msgid "
|
793 |
msgstr ""
|
794 |
|
795 |
-
#: includes/
|
796 |
-
msgid "
|
|
|
|
|
797 |
msgstr ""
|
798 |
|
799 |
-
#: includes/
|
800 |
-
msgid "
|
801 |
msgstr ""
|
802 |
|
803 |
-
#: includes/
|
804 |
-
msgid "
|
|
|
|
|
805 |
msgstr ""
|
806 |
|
807 |
-
#: includes/
|
808 |
-
msgid "
|
809 |
msgstr ""
|
810 |
|
811 |
-
#: includes/
|
812 |
-
msgid "
|
813 |
msgstr ""
|
814 |
|
815 |
-
#: includes/
|
816 |
-
msgid "
|
817 |
msgstr ""
|
818 |
|
819 |
-
#: includes/
|
820 |
-
msgid "
|
821 |
msgstr ""
|
822 |
|
823 |
-
#: includes/
|
824 |
-
|
825 |
-
#. %3$s - opening <a> HTML link tag, %4$s closing </a> HTML link tag
|
826 |
-
msgid ""
|
827 |
-
"The product catalog visibility has been set to \"hidden\", as a matching "
|
828 |
-
"product could not be found in Square on %1$s at %2$s. %3$sCheck sync "
|
829 |
-
"records%4$s."
|
830 |
msgstr ""
|
831 |
|
832 |
-
#: includes/
|
833 |
-
|
834 |
-
msgid "Updated data for %d product."
|
835 |
-
msgid_plural "Updated data for %d products."
|
836 |
-
msgstr[0] ""
|
837 |
-
msgstr[1] ""
|
838 |
-
|
839 |
-
#: includes/Lifecycle.php:185
|
840 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/Lifecycle.php:374
|
841 |
-
msgid "Awesome"
|
842 |
msgstr ""
|
843 |
|
844 |
-
#: includes/
|
845 |
-
|
846 |
-
msgid "Congratulations"
|
847 |
msgstr ""
|
848 |
|
849 |
-
#: includes/
|
850 |
-
msgid "
|
851 |
msgstr ""
|
852 |
|
853 |
-
#: includes/
|
854 |
-
|
855 |
-
msgid "Fantastic"
|
856 |
msgstr ""
|
857 |
|
858 |
-
#: includes/
|
859 |
-
|
860 |
-
#. translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a>
|
861 |
-
#. tag, %4$s - <a> tag, %5$s - </a> tag
|
862 |
-
msgid ""
|
863 |
-
"Are you having a great experience with %1$s so far? Please consider "
|
864 |
-
"%2$sleaving a review%3$s! If things aren't going quite as expected, we're "
|
865 |
-
"happy to help -- please %4$sreach out to our support team%5$s."
|
866 |
msgstr ""
|
867 |
|
868 |
-
#: includes/
|
869 |
-
msgid ""
|
870 |
-
"Heads up! There may be a problem with your connection to Square. In order "
|
871 |
-
"to continue accepting payments, please %1$sdisconnect and re-connect your "
|
872 |
-
"site%2$s."
|
873 |
msgstr ""
|
874 |
|
875 |
-
#: includes/
|
876 |
-
msgid "
|
877 |
msgstr ""
|
878 |
|
879 |
-
#: includes/
|
880 |
-
msgid "
|
881 |
msgstr ""
|
882 |
|
883 |
-
#: includes/
|
884 |
-
|
885 |
-
|
|
|
886 |
msgstr ""
|
887 |
|
888 |
-
#: includes/
|
889 |
-
|
|
|
890 |
msgstr ""
|
891 |
|
892 |
-
#: includes/
|
893 |
-
|
894 |
-
|
895 |
-
msgid ""
|
896 |
-
"%1$s%2$d products%3$s are marked \"sync with Square\". %4$sStart a new sync "
|
897 |
-
"now »%5$s"
|
898 |
msgstr ""
|
899 |
|
900 |
-
#: includes/
|
901 |
-
|
902 |
-
#. <a> tag, %4$s - </a> tag
|
903 |
-
msgid ""
|
904 |
-
"%1$sNo products%2$s are marked \"sync with Square\". %3$sUpdate your "
|
905 |
-
"products to sync data »%4$s"
|
906 |
msgstr ""
|
907 |
|
908 |
-
#: includes/
|
909 |
-
|
910 |
-
"
|
911 |
-
"stock management is disabled. Please %1$senable stock management%2$s to "
|
912 |
-
"ensure product inventory counts are kept in sync."
|
913 |
msgstr ""
|
914 |
|
915 |
-
#: includes/
|
916 |
-
|
|
|
|
|
917 |
msgstr ""
|
918 |
|
919 |
-
#: includes/
|
920 |
-
|
921 |
-
msgid "To get started, %1$sconnect with Square »%2$s"
|
922 |
msgstr ""
|
923 |
|
924 |
-
#: includes/
|
925 |
-
|
926 |
-
msgid "Thanks for installing %1$s!"
|
927 |
msgstr ""
|
928 |
|
929 |
-
#: includes/
|
930 |
-
|
931 |
-
#. %3$s - opening <a> HTML link tag, %4$s - closing </a> HTML link tag, %5$s -
|
932 |
-
#. opening <a> HTML link tag, %6$s - closing </a> HTML link tag
|
933 |
-
msgid ""
|
934 |
-
"%1$s has been updated to version %2$s. In order to continue syncing product "
|
935 |
-
"inventory, please make sure to disconnect and reconnect with Square from "
|
936 |
-
"the %3$splugin settings%4$s and re-sync your products. Read more in the "
|
937 |
-
"%5$supdated documentation%6$s."
|
938 |
msgstr ""
|
939 |
|
940 |
-
#: includes/
|
941 |
-
|
942 |
-
#. 2-character country code, %4$s - comma separated list of 2-character country
|
943 |
-
#. codes
|
944 |
-
msgid ""
|
945 |
-
"%1$sWooCommerce Square:%2$s Your base country is %3$s, but Square can’t "
|
946 |
-
"accept transactions from merchants outside of %4$s."
|
947 |
msgstr ""
|
948 |
|
949 |
-
#: includes/
|
950 |
-
|
951 |
-
#. <a> tag, %4$s - </a> tag
|
952 |
-
msgid ""
|
953 |
-
"%1$sWooCommerce Square:%2$s It looks like your site does not support "
|
954 |
-
"background processing, which means large numbers of products may not sync "
|
955 |
-
"successfully with Square. %3$sRead more here%4$s on how to resolve this."
|
956 |
msgstr ""
|
957 |
|
958 |
-
#: includes/
|
959 |
-
|
960 |
-
#. <a> tag, %4$s - </a> tag
|
961 |
-
msgid ""
|
962 |
-
"%1$sWooCommerce Square:%2$s Automatic refreshing of the connection to "
|
963 |
-
"Square is inactive. Please disconnect and reconnect to resolve."
|
964 |
msgstr ""
|
965 |
|
966 |
-
#: includes/
|
967 |
-
|
968 |
-
"
|
969 |
-
"but Square does not support syncing tax-inclusive prices. Please make sure "
|
970 |
-
"your Square tax rates match your WooCommerce tax rates."
|
971 |
msgstr ""
|
972 |
|
973 |
-
#: includes/
|
974 |
-
msgid ""
|
975 |
-
"Heads up! Your store currency is %1$s but your configured Square business "
|
976 |
-
"location currency is %2$s, so payments cannot be processed. Please "
|
977 |
-
"%3$schoose a different business location%4$s or change your %5$sshop "
|
978 |
-
"currency%6$s."
|
979 |
msgstr ""
|
980 |
|
981 |
-
|
982 |
-
msgid "
|
983 |
msgstr ""
|
984 |
|
985 |
-
#: includes/
|
986 |
-
|
987 |
-
msgid ""
|
988 |
-
"Sync your products and inventory and also accept credit and debit card "
|
989 |
-
"payments at checkout. %1$sClick here%2$s to configure payments."
|
990 |
msgstr ""
|
991 |
|
992 |
-
#: includes/
|
993 |
msgid ""
|
994 |
-
"
|
995 |
-
"
|
996 |
msgstr ""
|
997 |
|
998 |
-
#: includes/
|
999 |
-
|
|
|
1000 |
msgstr ""
|
1001 |
|
1002 |
-
#: includes/
|
1003 |
-
|
|
|
1004 |
msgstr ""
|
1005 |
|
1006 |
-
#: includes/
|
1007 |
-
msgid ""
|
1008 |
-
"After enabling you’ll see a new Sandbox settings section with two fields; "
|
1009 |
-
"Sandbox Application ID & Sandbox Access Token."
|
1010 |
msgstr ""
|
1011 |
|
1012 |
-
#: includes/
|
1013 |
-
msgid "
|
|
|
|
|
1014 |
msgstr ""
|
1015 |
|
1016 |
-
#: includes/
|
1017 |
-
|
1018 |
-
msgid "Sandbox details can be created at: %s"
|
1019 |
msgstr ""
|
1020 |
|
1021 |
-
#: includes/
|
1022 |
-
|
1023 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1024 |
|
1025 |
-
#: includes/
|
1026 |
msgid ""
|
1027 |
-
"
|
1028 |
-
"
|
1029 |
msgstr ""
|
1030 |
|
1031 |
-
#: includes/
|
1032 |
-
msgid "
|
1033 |
msgstr ""
|
1034 |
|
1035 |
-
#: includes/
|
1036 |
-
msgid ""
|
1037 |
-
"Access Token for the Sandbox Test Account, see the details in the Sandbox "
|
1038 |
-
"Test Account section. Make sure you use the correct Sandbox Access Token "
|
1039 |
-
"for your application. For a given Sandbox Test Account, each Authorized "
|
1040 |
-
"Application is assigned a different Access Token."
|
1041 |
msgstr ""
|
1042 |
|
1043 |
-
#: includes/
|
1044 |
-
msgid "
|
1045 |
msgstr ""
|
1046 |
|
1047 |
-
#: includes/
|
1048 |
-
|
1049 |
-
#. <a> tag, %4$s - </a> tag
|
1050 |
-
msgid ""
|
1051 |
-
"Select a location to link to this site. Only %1$sactive%2$s "
|
1052 |
-
"%3$slocations%4$s that support credit card processing in Square can be "
|
1053 |
-
"linked."
|
1054 |
msgstr ""
|
1055 |
|
1056 |
-
#: includes/
|
1057 |
-
msgid "
|
1058 |
msgstr ""
|
1059 |
|
1060 |
-
#: includes/
|
1061 |
-
|
1062 |
-
#. <a> tag, %4$s - </a> tag
|
1063 |
-
msgid ""
|
1064 |
-
"Choose where you will update data for synced products. Inventory in Square "
|
1065 |
-
"is %1$salways%2$s checked for adjustments when sync is enabled. %3$sClick "
|
1066 |
-
"here%4$s to read more about choosing a system of record."
|
1067 |
msgstr ""
|
1068 |
|
1069 |
-
#: includes/
|
1070 |
-
msgid "
|
1071 |
msgstr ""
|
1072 |
|
1073 |
-
|
1074 |
-
msgid "
|
1075 |
msgstr ""
|
1076 |
|
1077 |
-
#: includes/
|
1078 |
-
msgid "
|
1079 |
msgstr ""
|
1080 |
|
1081 |
-
#: includes/
|
1082 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1083 |
msgstr ""
|
1084 |
|
1085 |
-
#: includes/
|
1086 |
-
msgid "
|
1087 |
msgstr ""
|
1088 |
|
1089 |
-
#: includes/
|
1090 |
-
msgid "
|
1091 |
msgstr ""
|
1092 |
|
1093 |
-
#: includes/
|
1094 |
-
msgid ""
|
1095 |
-
"Products not found in Square will be hidden in the WooCommerce product "
|
1096 |
-
"catalog."
|
1097 |
msgstr ""
|
1098 |
|
1099 |
-
#: includes/
|
1100 |
-
msgid ""
|
1101 |
-
"Run an import to create new products in this WooCommerce store for each new "
|
1102 |
-
"product created in Square that has a unique SKU not existing in here. Needs "
|
1103 |
-
"to be run each time new items are created in Square."
|
1104 |
msgstr ""
|
1105 |
|
1106 |
-
#: includes/
|
1107 |
-
|
|
|
|
|
|
|
1108 |
msgstr ""
|
1109 |
|
1110 |
-
#: includes/
|
1111 |
-
|
1112 |
-
|
|
|
|
|
|
|
|
|
|
|
1113 |
msgstr ""
|
1114 |
|
1115 |
-
#: includes/
|
1116 |
-
|
|
|
|
|
|
|
1117 |
msgstr ""
|
1118 |
|
1119 |
-
#: includes/
|
1120 |
-
msgid "
|
1121 |
msgstr ""
|
1122 |
|
1123 |
-
#: includes/
|
1124 |
-
msgid "
|
1125 |
-
msgid_plural "Updated data for %d categories."
|
1126 |
-
msgstr[0] ""
|
1127 |
-
msgstr[1] ""
|
1128 |
-
|
1129 |
-
#: includes/Sync/Interval_Polling.php:111
|
1130 |
-
msgid ""
|
1131 |
-
"Product category data could not be updated from Square. Invalid API "
|
1132 |
-
"response."
|
1133 |
msgstr ""
|
1134 |
|
1135 |
-
#: includes/
|
1136 |
-
|
1137 |
-
msgid "Product %s could not be updated in Square."
|
1138 |
msgstr ""
|
1139 |
|
1140 |
-
#: includes/
|
1141 |
-
|
1142 |
-
#. variation name, %3$s - failure reason
|
1143 |
-
msgid "Could not import \"%1$s - %2$s\" from Square. %3$s"
|
1144 |
msgstr ""
|
1145 |
|
1146 |
-
#: includes/
|
1147 |
-
|
1148 |
-
|
|
|
|
|
|
|
1149 |
msgstr ""
|
1150 |
|
1151 |
-
#: includes/
|
1152 |
-
msgid "
|
1153 |
msgstr ""
|
1154 |
|
1155 |
-
#: includes/
|
1156 |
-
msgid "
|
1157 |
msgstr ""
|
1158 |
|
1159 |
-
#: includes/
|
1160 |
-
msgid "
|
1161 |
msgstr ""
|
1162 |
|
1163 |
-
#: includes/
|
1164 |
-
#. translators: Placeholders: %1$s -
|
1165 |
-
|
|
|
1166 |
msgstr ""
|
1167 |
|
1168 |
-
#: includes/
|
1169 |
-
|
1170 |
-
|
|
|
|
|
|
|
1171 |
msgstr ""
|
1172 |
|
1173 |
-
#: includes/
|
1174 |
-
|
1175 |
-
msgid "Invalid product type - the product type must be any of these: %s"
|
1176 |
msgstr ""
|
1177 |
|
1178 |
-
#: includes/
|
1179 |
-
|
1180 |
-
msgid "Could not update %1$s from Square. %2$s"
|
1181 |
msgstr ""
|
1182 |
|
1183 |
-
#: includes/
|
1184 |
-
|
1185 |
-
|
|
|
1186 |
msgstr ""
|
1187 |
|
1188 |
-
#: includes/
|
1189 |
-
msgid "
|
1190 |
msgstr ""
|
1191 |
|
1192 |
-
#: includes/
|
1193 |
-
|
|
|
1194 |
msgstr ""
|
1195 |
|
1196 |
-
#: includes/
|
1197 |
-
|
|
|
|
|
|
|
|
|
1198 |
msgstr ""
|
1199 |
|
1200 |
-
#: includes/
|
1201 |
-
|
1202 |
-
|
|
|
|
|
|
|
1203 |
msgstr ""
|
1204 |
|
1205 |
-
#: includes/
|
1206 |
-
#:
|
1207 |
-
#:
|
1208 |
-
|
|
|
|
|
1209 |
msgstr ""
|
1210 |
|
1211 |
-
#: includes/
|
1212 |
-
msgid "
|
1213 |
msgstr ""
|
1214 |
|
1215 |
-
#: includes/
|
1216 |
-
|
|
|
1217 |
msgstr ""
|
1218 |
|
1219 |
-
#: includes/
|
1220 |
-
|
|
|
|
|
|
|
|
|
1221 |
msgstr ""
|
1222 |
|
1223 |
-
#: includes/
|
1224 |
-
msgid "
|
1225 |
msgstr ""
|
1226 |
|
1227 |
-
#: includes/
|
1228 |
-
msgid "
|
1229 |
msgstr ""
|
1230 |
|
1231 |
-
#: includes/
|
1232 |
-
|
|
|
1233 |
msgstr ""
|
1234 |
|
1235 |
-
#: includes/
|
1236 |
-
#: includes/
|
1237 |
-
msgid "
|
1238 |
msgstr ""
|
1239 |
|
1240 |
-
#: includes/
|
1241 |
-
|
|
|
1242 |
msgstr ""
|
1243 |
|
1244 |
-
#: includes/
|
1245 |
-
|
|
|
1246 |
msgstr ""
|
1247 |
|
1248 |
-
#: includes/
|
1249 |
-
|
|
|
1250 |
msgstr ""
|
1251 |
|
1252 |
-
#:
|
1253 |
-
#:
|
1254 |
-
|
1255 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:89
|
1256 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_wpPostStore_PostTypeRegistrar.php:19
|
1257 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_wpPostStore_PostTypeRegistrar.php:30
|
1258 |
-
msgid "Scheduled Actions"
|
1259 |
msgstr ""
|
1260 |
|
1261 |
-
#:
|
1262 |
-
|
|
|
1263 |
msgstr ""
|
1264 |
|
1265 |
-
#:
|
1266 |
-
|
|
|
1267 |
msgstr ""
|
1268 |
|
1269 |
-
#:
|
1270 |
-
msgid "
|
1271 |
msgstr ""
|
1272 |
|
1273 |
-
#:
|
1274 |
-
msgid "
|
1275 |
msgstr ""
|
1276 |
|
1277 |
-
#:
|
1278 |
-
msgid "
|
1279 |
msgstr ""
|
1280 |
|
1281 |
-
#:
|
1282 |
-
msgid "
|
1283 |
msgstr ""
|
1284 |
|
1285 |
-
#:
|
1286 |
-
msgid "
|
1287 |
msgstr ""
|
1288 |
|
1289 |
-
#:
|
1290 |
-
msgid "
|
1291 |
msgstr ""
|
1292 |
|
1293 |
-
#:
|
1294 |
-
msgid "
|
1295 |
msgstr ""
|
1296 |
|
1297 |
-
#:
|
1298 |
-
msgid "
|
1299 |
msgstr ""
|
1300 |
|
1301 |
-
#:
|
1302 |
-
msgid "
|
1303 |
msgstr ""
|
1304 |
|
1305 |
-
#:
|
1306 |
-
msgid "
|
1307 |
-
msgid_plural "%s years"
|
1308 |
-
msgstr[0] ""
|
1309 |
-
msgstr[1] ""
|
1310 |
-
|
1311 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:147
|
1312 |
-
msgid "%s month"
|
1313 |
-
msgid_plural "%s months"
|
1314 |
-
msgstr[0] ""
|
1315 |
-
msgstr[1] ""
|
1316 |
-
|
1317 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:151
|
1318 |
-
msgid "%s week"
|
1319 |
-
msgid_plural "%s weeks"
|
1320 |
-
msgstr[0] ""
|
1321 |
-
msgstr[1] ""
|
1322 |
-
|
1323 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:155
|
1324 |
-
msgid "%s day"
|
1325 |
-
msgid_plural "%s days"
|
1326 |
-
msgstr[0] ""
|
1327 |
-
msgstr[1] ""
|
1328 |
-
|
1329 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:159
|
1330 |
-
msgid "%s hour"
|
1331 |
-
msgid_plural "%s hours"
|
1332 |
-
msgstr[0] ""
|
1333 |
-
msgstr[1] ""
|
1334 |
-
|
1335 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:163
|
1336 |
-
msgid "%s minute"
|
1337 |
-
msgid_plural "%s minutes"
|
1338 |
-
msgstr[0] ""
|
1339 |
-
msgstr[1] ""
|
1340 |
-
|
1341 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:167
|
1342 |
-
msgid "%s second"
|
1343 |
-
msgid_plural "%s seconds"
|
1344 |
-
msgstr[0] ""
|
1345 |
-
msgstr[1] ""
|
1346 |
-
|
1347 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_ListTable.php:194
|
1348 |
-
msgid "Now!"
|
1349 |
msgstr ""
|
1350 |
|
1351 |
-
#:
|
1352 |
-
msgid "
|
1353 |
msgstr ""
|
1354 |
|
1355 |
-
#:
|
1356 |
-
msgid "
|
1357 |
msgstr ""
|
1358 |
|
1359 |
-
#:
|
1360 |
-
msgid "
|
1361 |
msgstr ""
|
1362 |
|
1363 |
-
#:
|
1364 |
-
msgid ""
|
1365 |
-
"Maximum simultaneous batches already in progress (%s queues). No actions "
|
1366 |
-
"will be processed until the current batches are complete."
|
1367 |
msgstr ""
|
1368 |
|
1369 |
-
#:
|
1370 |
-
|
|
|
1371 |
msgstr ""
|
1372 |
|
1373 |
-
#:
|
1374 |
-
msgid "
|
1375 |
msgstr ""
|
1376 |
|
1377 |
-
#:
|
1378 |
-
|
|
|
1379 |
msgstr ""
|
1380 |
|
1381 |
-
#:
|
1382 |
-
|
|
|
1383 |
msgstr ""
|
1384 |
|
1385 |
-
#:
|
1386 |
-
|
|
|
1387 |
msgstr ""
|
1388 |
|
1389 |
-
#:
|
1390 |
-
|
|
|
1391 |
msgstr ""
|
1392 |
|
1393 |
-
#:
|
1394 |
-
|
|
|
1395 |
msgstr ""
|
1396 |
|
1397 |
-
#:
|
1398 |
-
|
|
|
1399 |
msgstr ""
|
1400 |
|
1401 |
-
#:
|
1402 |
-
|
|
|
|
|
|
|
1403 |
msgstr ""
|
1404 |
|
1405 |
-
#:
|
1406 |
-
|
|
|
|
|
|
|
|
|
1407 |
msgstr ""
|
1408 |
|
1409 |
-
#:
|
1410 |
-
|
|
|
1411 |
msgstr ""
|
1412 |
|
1413 |
-
#:
|
1414 |
-
|
|
|
|
|
1415 |
msgstr ""
|
1416 |
|
1417 |
-
#:
|
1418 |
-
msgid "
|
1419 |
msgstr ""
|
1420 |
|
1421 |
-
#:
|
1422 |
-
msgid "
|
1423 |
msgstr ""
|
1424 |
|
1425 |
-
#:
|
1426 |
-
msgid "
|
1427 |
msgstr ""
|
1428 |
|
1429 |
-
#:
|
1430 |
-
msgid "
|
1431 |
msgstr ""
|
1432 |
|
1433 |
-
#:
|
1434 |
-
msgid "
|
1435 |
msgstr ""
|
1436 |
|
1437 |
-
#:
|
1438 |
-
|
1439 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_wpPostStore.php:268
|
1440 |
-
msgid "Invalid schedule. Cannot save action."
|
1441 |
msgstr ""
|
1442 |
|
1443 |
-
#:
|
1444 |
-
msgid "
|
1445 |
msgstr ""
|
1446 |
|
1447 |
-
#:
|
1448 |
-
msgid "
|
1449 |
msgstr ""
|
1450 |
|
1451 |
-
#:
|
1452 |
-
|
|
|
1453 |
msgstr ""
|
1454 |
|
1455 |
-
#:
|
1456 |
-
|
|
|
|
|
1457 |
msgstr ""
|
1458 |
|
1459 |
-
#:
|
1460 |
-
#. translators: %s
|
1461 |
-
msgid "
|
1462 |
msgstr ""
|
1463 |
|
1464 |
-
#:
|
1465 |
-
|
|
|
|
|
1466 |
msgstr ""
|
1467 |
|
1468 |
-
#:
|
1469 |
-
|
|
|
|
|
1470 |
msgstr ""
|
1471 |
|
1472 |
-
#:
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
msgstr[1] ""
|
1477 |
-
|
1478 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_WPCLI_QueueRunner.php:109
|
1479 |
-
msgid "The claim has been lost. Aborting current batch."
|
1480 |
msgstr ""
|
1481 |
|
1482 |
-
#:
|
1483 |
-
#. translators: %s
|
1484 |
-
|
|
|
1485 |
msgstr ""
|
1486 |
|
1487 |
-
#:
|
1488 |
-
|
1489 |
-
|
|
|
1490 |
msgstr ""
|
1491 |
|
1492 |
-
#:
|
1493 |
-
#. translators: %1$s
|
1494 |
-
#. message
|
1495 |
-
msgid "
|
1496 |
msgstr ""
|
1497 |
|
1498 |
-
#:
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
msgstr[1] ""
|
1503 |
-
|
1504 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_WPCLI_QueueRunner.php:187
|
1505 |
-
msgid "Attempting to reduce used memory..."
|
1506 |
msgstr ""
|
1507 |
|
1508 |
-
#:
|
1509 |
-
#. translators: %
|
1510 |
-
|
1511 |
-
|
1512 |
-
msgstr[0] ""
|
1513 |
-
msgstr[1] ""
|
1514 |
-
|
1515 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_WPCLI_Scheduler_command.php:104
|
1516 |
-
#. translators: %d refers to the total number of batches executed
|
1517 |
-
msgid "%d batch executed."
|
1518 |
-
msgid_plural "%d batches executed."
|
1519 |
-
msgstr[0] ""
|
1520 |
-
msgstr[1] ""
|
1521 |
-
|
1522 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_WPCLI_Scheduler_command.php:123
|
1523 |
-
#. translators: %s refers to the exception error message.
|
1524 |
-
msgid "There was an error running the action scheduler: %s"
|
1525 |
msgstr ""
|
1526 |
|
1527 |
-
#:
|
1528 |
-
#. translators: %
|
1529 |
-
|
1530 |
-
|
1531 |
-
msgstr
|
1532 |
-
msgstr[1] ""
|
1533 |
|
1534 |
-
#:
|
1535 |
-
|
|
|
|
|
1536 |
msgstr ""
|
1537 |
|
1538 |
-
#:
|
1539 |
-
|
|
|
|
|
|
|
1540 |
msgstr ""
|
1541 |
|
1542 |
-
#:
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
msgid "Unidentified action %s"
|
1547 |
msgstr ""
|
1548 |
|
1549 |
-
#:
|
1550 |
-
msgid "
|
|
|
|
|
1551 |
msgstr ""
|
1552 |
|
1553 |
-
#:
|
1554 |
-
|
|
|
|
|
1555 |
msgstr ""
|
1556 |
|
1557 |
-
#:
|
1558 |
-
msgid "
|
1559 |
msgstr ""
|
1560 |
|
1561 |
-
#:
|
1562 |
-
msgid "
|
|
|
|
|
|
|
1563 |
msgstr ""
|
1564 |
|
1565 |
-
#:
|
1566 |
-
msgid "
|
1567 |
msgstr ""
|
1568 |
|
1569 |
-
#:
|
1570 |
-
msgid "
|
|
|
|
|
1571 |
msgstr ""
|
1572 |
|
1573 |
-
#:
|
1574 |
-
msgid "
|
1575 |
-
|
1576 |
-
msgstr[0] ""
|
1577 |
-
msgstr[1] ""
|
1578 |
|
1579 |
-
#:
|
1580 |
-
msgid "
|
1581 |
-
|
1582 |
-
msgstr[0] ""
|
1583 |
-
msgstr[1] ""
|
1584 |
|
1585 |
-
#:
|
1586 |
-
msgid "
|
1587 |
msgstr ""
|
1588 |
|
1589 |
-
#:
|
1590 |
-
msgid "
|
1591 |
msgstr ""
|
1592 |
|
1593 |
-
#:
|
1594 |
-
msgid "
|
1595 |
msgstr ""
|
1596 |
|
1597 |
-
#:
|
1598 |
-
msgid "
|
1599 |
msgstr ""
|
1600 |
|
1601 |
-
#:
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
msgstr ""
|
1606 |
|
1607 |
-
#:
|
1608 |
-
|
|
|
|
|
|
|
1609 |
msgstr ""
|
1610 |
|
1611 |
-
#:
|
1612 |
-
|
|
|
|
|
|
|
1613 |
msgstr ""
|
1614 |
|
1615 |
-
#:
|
1616 |
-
|
1617 |
-
msgid "View Action"
|
1618 |
msgstr ""
|
1619 |
|
1620 |
-
#:
|
1621 |
-
msgid "
|
|
|
|
|
1622 |
msgstr ""
|
1623 |
|
1624 |
-
#:
|
1625 |
-
msgid "
|
1626 |
msgstr ""
|
1627 |
|
1628 |
-
#:
|
1629 |
-
msgid "
|
1630 |
msgstr ""
|
1631 |
|
1632 |
-
#:
|
1633 |
-
|
|
|
|
|
|
|
1634 |
msgstr ""
|
1635 |
|
1636 |
-
#:
|
1637 |
-
|
|
|
1638 |
msgstr ""
|
1639 |
|
1640 |
-
#:
|
1641 |
-
|
|
|
|
|
1642 |
msgstr ""
|
1643 |
|
1644 |
-
#:
|
1645 |
-
|
1646 |
-
|
1647 |
-
"
|
1648 |
msgstr ""
|
1649 |
|
1650 |
-
#:
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1654 |
msgstr ""
|
1655 |
|
1656 |
-
#:
|
1657 |
-
msgid "
|
1658 |
msgstr ""
|
1659 |
|
1660 |
-
#:
|
1661 |
-
#. translators: Placeholders: %s -
|
1662 |
-
|
|
|
1663 |
msgstr ""
|
1664 |
|
1665 |
-
#:
|
1666 |
-
msgid "
|
1667 |
msgstr ""
|
1668 |
|
1669 |
-
#:
|
1670 |
-
msgid "
|
1671 |
msgstr ""
|
1672 |
|
1673 |
-
#:
|
1674 |
-
|
1675 |
-
msgid "Welcome to %s!"
|
1676 |
msgstr ""
|
1677 |
|
1678 |
-
#:
|
1679 |
-
msgid ""
|
1680 |
-
|
1681 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1682 |
msgstr ""
|
1683 |
|
1684 |
-
#:
|
1685 |
-
msgid "
|
1686 |
msgstr ""
|
1687 |
|
1688 |
-
#:
|
1689 |
-
msgid "
|
1690 |
msgstr ""
|
1691 |
|
1692 |
-
#:
|
1693 |
-
msgid "
|
1694 |
msgstr ""
|
1695 |
|
1696 |
-
#:
|
1697 |
-
|
1698 |
-
msgid "View the Docs"
|
1699 |
msgstr ""
|
1700 |
|
1701 |
-
#:
|
1702 |
-
msgid "
|
1703 |
msgstr ""
|
1704 |
|
1705 |
-
#:
|
1706 |
-
msgid "
|
1707 |
msgstr ""
|
1708 |
|
1709 |
-
#:
|
1710 |
-
msgid "
|
1711 |
msgstr ""
|
1712 |
|
1713 |
-
#:
|
1714 |
-
msgid "
|
1715 |
msgstr ""
|
1716 |
|
1717 |
-
#:
|
1718 |
-
|
1719 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1720 |
msgstr ""
|
1721 |
|
1722 |
-
#:
|
1723 |
-
msgid "
|
1724 |
msgstr ""
|
1725 |
|
1726 |
-
#:
|
1727 |
-
|
|
|
1728 |
msgstr ""
|
1729 |
|
1730 |
-
#:
|
1731 |
-
|
|
|
|
|
|
|
|
|
1732 |
msgstr ""
|
1733 |
|
1734 |
-
#:
|
|
|
1735 |
msgid ""
|
1736 |
-
"
|
1737 |
-
"
|
1738 |
-
|
1739 |
-
"
|
1740 |
-
|
1741 |
-
msgstr[0] ""
|
1742 |
-
msgstr[1] ""
|
1743 |
|
1744 |
-
#:
|
|
|
|
|
1745 |
msgid ""
|
1746 |
-
"
|
1747 |
-
"%
|
1748 |
msgid_plural ""
|
1749 |
-
"
|
1750 |
-
"%
|
1751 |
msgstr[0] ""
|
1752 |
msgstr[1] ""
|
1753 |
|
1754 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1755 |
msgid ""
|
1756 |
-
"
|
1757 |
-
"
|
1758 |
msgstr ""
|
1759 |
|
1760 |
-
#:
|
1761 |
msgid ""
|
1762 |
-
"
|
1763 |
-
"WooCommerce
|
1764 |
msgstr ""
|
1765 |
|
1766 |
-
#:
|
1767 |
-
|
1768 |
-
#. number
|
1769 |
-
msgid "%1$s requires WooCommerce %2$s or newer"
|
1770 |
msgstr ""
|
1771 |
|
1772 |
-
#:
|
1773 |
-
|
1774 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1775 |
msgstr ""
|
1776 |
|
1777 |
-
#:
|
1778 |
#. translators: Placeholders: %1$s - plugin name, %2$s - a PHP
|
1779 |
#. extension/comma-separated list of PHP extensions
|
1780 |
msgid ""
|
@@ -1787,7 +1846,7 @@ msgid_plural ""
|
|
1787 |
msgstr[0] ""
|
1788 |
msgstr[1] ""
|
1789 |
|
1790 |
-
#:
|
1791 |
#. translators: Placeholders: %1$s - plugin name, %2$s - a PHP
|
1792 |
#. function/comma-separated list of PHP functions
|
1793 |
msgid ""
|
@@ -1799,24 +1858,25 @@ msgid_plural ""
|
|
1799 |
msgstr[0] ""
|
1800 |
msgstr[1] ""
|
1801 |
|
1802 |
-
#:
|
1803 |
#. translators: Placeholders: %s - plugin name
|
1804 |
msgid ""
|
1805 |
"%s may behave unexpectedly because the following PHP configuration settings "
|
1806 |
"are required:"
|
1807 |
msgstr ""
|
1808 |
|
1809 |
-
#:
|
|
|
1810 |
msgid "%s or higher"
|
1811 |
msgstr ""
|
1812 |
|
1813 |
-
#:
|
1814 |
msgid ""
|
1815 |
"Please contact your hosting provider or server administrator to configure "
|
1816 |
"these settings."
|
1817 |
msgstr ""
|
1818 |
|
1819 |
-
#:
|
1820 |
#. translators: Placeholders: %1$s - <strong>, %2$s - </strong>
|
1821 |
msgid ""
|
1822 |
"Hey there! We've noticed that your server is running %1$san outdated "
|
@@ -1831,7 +1891,7 @@ msgid ""
|
|
1831 |
"resources to help you upgrade%5$s and to explain PHP versions further."
|
1832 |
msgstr ""
|
1833 |
|
1834 |
-
#:
|
1835 |
#. translators: Placeholders: %1$s - WooCommerce version number, %2$s -
|
1836 |
#. <strong>, %3$s - </strong>, %4$s - Plugin name, %5$s - <a> tag, %6$s - </a>
|
1837 |
#. tag
|
@@ -1842,1400 +1902,1338 @@ msgid ""
|
|
1842 |
"soon as possible."
|
1843 |
msgstr ""
|
1844 |
|
1845 |
-
#:
|
1846 |
-
|
1847 |
-
msgid "You cannot clone instances of %s."
|
1848 |
-
msgstr ""
|
1849 |
-
|
1850 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-plugin.php:308
|
1851 |
-
#. translators: Placeholders: %s - plugin name
|
1852 |
-
msgid "You cannot unserialize instances of %s."
|
1853 |
-
msgstr ""
|
1854 |
-
|
1855 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-plugin.php:529
|
1856 |
-
#. translators: Docs as in Documentation
|
1857 |
-
msgid "Docs"
|
1858 |
-
msgstr ""
|
1859 |
-
|
1860 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-plugin.php:622
|
1861 |
-
msgid "%1$s - A minimum of %2$s is required."
|
1862 |
msgstr ""
|
1863 |
|
1864 |
-
#:
|
1865 |
-
|
|
|
1866 |
msgstr ""
|
1867 |
|
1868 |
-
#:
|
1869 |
-
|
|
|
|
|
|
|
|
|
|
|
1870 |
msgstr ""
|
1871 |
|
1872 |
-
#:
|
|
|
|
|
1873 |
msgid ""
|
1874 |
-
"
|
1875 |
-
"
|
|
|
1876 |
msgstr ""
|
1877 |
|
1878 |
-
#:
|
1879 |
-
|
1880 |
-
#.
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/payment-tokens/class-sv-wc-payment-gateway-payment-tokens-handler.php:163
|
1887 |
-
#. translators: Placeholders: %1$s - status code, %2$s - status message
|
1888 |
-
#. translators: Placeholders: %1$s - payment request response status code, %2$s
|
1889 |
-
#. - payment request response status message
|
1890 |
-
msgid "Status code %1$s: %2$s"
|
1891 |
-
msgstr ""
|
1892 |
-
|
1893 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Payment_Handler.php:154
|
1894 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2354
|
1895 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/payment-tokens/class-sv-wc-payment-gateway-payment-tokens-handler.php:166
|
1896 |
-
#. translators: Placeholders: %s - status code
|
1897 |
-
#. translators: Placeholders: %s - payment request response status code
|
1898 |
-
msgid "Status code: %s"
|
1899 |
-
msgstr ""
|
1900 |
-
|
1901 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Payment_Handler.php:157
|
1902 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2357
|
1903 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/payment-tokens/class-sv-wc-payment-gateway-payment-tokens-handler.php:169
|
1904 |
-
#. translators: Placeholders; %s - status message
|
1905 |
-
#. translators: Placeholders: %s - payment request response status message
|
1906 |
-
msgid "Status message: %s"
|
1907 |
-
msgstr ""
|
1908 |
-
|
1909 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Payment_Handler.php:162
|
1910 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2362
|
1911 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/payment-tokens/class-sv-wc-payment-gateway-payment-tokens-handler.php:176
|
1912 |
-
msgid "Transaction ID %s"
|
1913 |
msgstr ""
|
1914 |
|
1915 |
-
#:
|
1916 |
-
|
1917 |
-
#. translators: Placeholders: %s - payment gateway title (such as
|
1918 |
-
#. Authorize.net, Braintree, etc)
|
1919 |
-
msgid "%s duplicate transaction received"
|
1920 |
msgstr ""
|
1921 |
|
1922 |
-
#:
|
1923 |
-
|
1924 |
-
msgid "
|
1925 |
msgstr ""
|
1926 |
|
1927 |
-
#:
|
1928 |
-
|
1929 |
msgid ""
|
1930 |
-
"
|
1931 |
-
"
|
1932 |
-
msgstr ""
|
1933 |
-
|
1934 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Payment_Handler.php:273
|
1935 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-direct.php:851
|
1936 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:1732
|
1937 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/integrations/class-sv-wc-payment-gateway-integration-pre-orders.php:363
|
1938 |
-
#. translators: This is a message describing that the transaction in question
|
1939 |
-
#. only performed a credit card authorization and did not capture any funds.
|
1940 |
-
msgid "Authorization only transaction"
|
1941 |
-
msgstr ""
|
1942 |
-
|
1943 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/Handlers/Abstract_Payment_Handler.php:361
|
1944 |
-
#. translators: Placeholders: %s - payment gateway title
|
1945 |
-
msgid "%s Transaction Held for Review"
|
1946 |
msgstr ""
|
1947 |
|
1948 |
-
#:
|
1949 |
-
#. translators:
|
1950 |
-
msgid "%s
|
1951 |
msgstr ""
|
1952 |
|
1953 |
-
#:
|
1954 |
-
|
1955 |
-
msgid "
|
1956 |
msgstr ""
|
1957 |
|
1958 |
-
#:
|
1959 |
-
msgid "
|
1960 |
msgstr ""
|
1961 |
|
1962 |
-
#:
|
1963 |
-
|
|
|
1964 |
msgstr ""
|
1965 |
|
1966 |
-
#:
|
1967 |
-
|
|
|
1968 |
msgstr ""
|
1969 |
|
1970 |
-
#:
|
1971 |
-
msgid "
|
1972 |
msgstr ""
|
1973 |
|
1974 |
-
#:
|
1975 |
-
|
1976 |
-
#. Authorize.net, Braintree, etc), %2$s - transaction amount. Definitions:
|
1977 |
-
#. Capture, as in capture funds from a credit card.
|
1978 |
-
msgid "%1$s Capture of %2$s Approved"
|
1979 |
msgstr ""
|
1980 |
|
1981 |
-
#:
|
1982 |
-
|
1983 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-direct.php:755
|
1984 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2030
|
1985 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2261
|
1986 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2575
|
1987 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2620
|
1988 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/integrations/class-sv-wc-payment-gateway-integration-pre-orders.php:346
|
1989 |
-
#. translators: Placeholders: %s - transaction ID
|
1990 |
-
msgid "(Transaction ID %s)"
|
1991 |
msgstr ""
|
1992 |
|
1993 |
-
#:
|
1994 |
-
|
1995 |
-
#. Authorize.net, Braintree, etc), %2$s - failure message. Definitions:
|
1996 |
-
#. "capture" as in capturing funds from a credit card.
|
1997 |
-
msgid "%1$s Capture Failed: %2$s"
|
1998 |
msgstr ""
|
1999 |
|
2000 |
-
#:
|
2001 |
-
msgid "
|
2002 |
msgstr ""
|
2003 |
|
2004 |
-
#:
|
2005 |
msgid ""
|
2006 |
-
"
|
2007 |
-
"
|
2008 |
-
msgstr ""
|
2009 |
-
|
2010 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/class-sv-wc-payment-gateway-admin-order.php:166
|
2011 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/class-sv-wc-payment-gateway-admin-order.php:241
|
2012 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/class-sv-wc-payment-gateway-admin-order.php:304
|
2013 |
-
#. translators: verb, as in "Capture credit card charge". Used when an
|
2014 |
-
#. amount has been pre-authorized before, but funds have not yet been captured
|
2015 |
-
#. (taken) from the card. Capturing the charge will take the money from the
|
2016 |
-
#. credit card and put it in the merchant's pockets.
|
2017 |
-
msgid "Capture Charge"
|
2018 |
-
msgstr ""
|
2019 |
-
|
2020 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/class-sv-wc-payment-gateway-admin-order.php:294
|
2021 |
-
msgid "This charge has been fully captured."
|
2022 |
-
msgstr ""
|
2023 |
-
|
2024 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/admin/class-sv-wc-payment-gateway-admin-order.php:296
|
2025 |
-
msgid "This charge can no longer be captured."
|
2026 |
msgstr ""
|
2027 |
|
2028 |
-
#:
|
2029 |
-
msgid "
|
2030 |
msgstr ""
|
2031 |
|
2032 |
-
#:
|
2033 |
-
msgid "
|
2034 |
msgstr ""
|
2035 |
|
2036 |
-
#:
|
2037 |
-
msgid "
|
|
|
|
|
2038 |
msgstr ""
|
2039 |
|
2040 |
-
#:
|
2041 |
-
msgid "
|
2042 |
msgstr ""
|
2043 |
|
2044 |
-
#:
|
2045 |
-
|
2046 |
-
msgid "(%s)"
|
2047 |
msgstr ""
|
2048 |
|
2049 |
-
#:
|
2050 |
-
|
2051 |
-
msgid "
|
|
|
|
|
|
|
2052 |
msgstr ""
|
2053 |
|
2054 |
-
#:
|
2055 |
-
|
2056 |
-
msgid "Token ID"
|
2057 |
msgstr ""
|
2058 |
|
2059 |
-
#:
|
2060 |
-
|
2061 |
-
msgid "Card Type"
|
2062 |
msgstr ""
|
2063 |
|
2064 |
-
#:
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
msgstr ""
|
2070 |
|
2071 |
-
#:
|
2072 |
-
|
2073 |
-
msgid "Expiration (MM/YY)"
|
2074 |
msgstr ""
|
2075 |
|
2076 |
-
#:
|
2077 |
-
|
2078 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-privacy.php:298
|
2079 |
-
#. translators: e-check account type, HTML form field label
|
2080 |
-
msgid "Account Type"
|
2081 |
msgstr ""
|
2082 |
|
2083 |
-
#:
|
2084 |
-
msgid "
|
2085 |
msgstr ""
|
2086 |
|
2087 |
-
#:
|
2088 |
-
msgid "
|
2089 |
msgstr ""
|
2090 |
|
2091 |
-
#:
|
2092 |
-
msgid "
|
2093 |
msgstr ""
|
2094 |
|
2095 |
-
#:
|
2096 |
-
msgid "
|
2097 |
msgstr ""
|
2098 |
|
2099 |
-
#:
|
2100 |
-
|
2101 |
-
|
|
|
2102 |
msgstr ""
|
2103 |
|
2104 |
-
#:
|
2105 |
-
msgid "
|
2106 |
msgstr ""
|
2107 |
|
2108 |
-
#:
|
2109 |
-
|
2110 |
-
msgid "%s Payment Tokens"
|
2111 |
msgstr ""
|
2112 |
|
2113 |
-
#:
|
2114 |
-
|
2115 |
-
msgid "Customer ID"
|
2116 |
msgstr ""
|
2117 |
|
2118 |
-
#:
|
2119 |
-
msgid "This
|
2120 |
msgstr ""
|
2121 |
|
2122 |
-
#:
|
2123 |
-
|
2124 |
-
#. translators: environment as in a software environment (test/production)
|
2125 |
-
msgid "Environment"
|
2126 |
msgstr ""
|
2127 |
|
2128 |
-
#:
|
2129 |
-
msgid "
|
2130 |
msgstr ""
|
2131 |
|
2132 |
-
#:
|
2133 |
-
msgid "
|
2134 |
msgstr ""
|
2135 |
|
2136 |
-
#:
|
2137 |
-
msgid "
|
2138 |
msgstr ""
|
2139 |
|
2140 |
-
#:
|
2141 |
-
msgid "
|
2142 |
msgstr ""
|
2143 |
|
2144 |
-
#:
|
2145 |
-
msgid "
|
2146 |
msgstr ""
|
2147 |
|
2148 |
-
#:
|
2149 |
-
|
|
|
|
|
|
|
2150 |
msgstr ""
|
2151 |
|
2152 |
-
#:
|
2153 |
-
msgid "
|
2154 |
msgstr ""
|
2155 |
|
2156 |
-
#:
|
2157 |
-
|
|
|
|
|
|
|
2158 |
msgstr ""
|
2159 |
|
2160 |
-
#:
|
2161 |
-
|
|
|
|
|
|
|
|
|
2162 |
msgstr ""
|
2163 |
|
2164 |
-
#:
|
2165 |
-
|
|
|
2166 |
msgstr ""
|
2167 |
|
2168 |
-
#:
|
2169 |
-
msgid "
|
2170 |
msgstr ""
|
2171 |
|
2172 |
-
#:
|
2173 |
-
msgid "
|
2174 |
msgstr ""
|
2175 |
|
2176 |
-
#:
|
2177 |
-
msgid "
|
2178 |
msgstr ""
|
2179 |
|
2180 |
-
#:
|
2181 |
-
msgid "
|
2182 |
msgstr ""
|
2183 |
|
2184 |
-
#:
|
2185 |
-
msgid "
|
2186 |
msgstr ""
|
2187 |
|
2188 |
-
#:
|
2189 |
-
|
2190 |
-
msgid "An error occurred, please try again or try an alternate form of payment"
|
2191 |
msgstr ""
|
2192 |
|
2193 |
-
#:
|
2194 |
-
msgid ""
|
2195 |
-
"We cannot process your order with the payment information that you "
|
2196 |
-
"provided. Please use a different payment account or an alternate payment "
|
2197 |
-
"method."
|
2198 |
msgstr ""
|
2199 |
|
2200 |
-
#:
|
2201 |
-
msgid ""
|
2202 |
-
"This order is being placed on hold for review. Please contact us to "
|
2203 |
-
"complete the transaction."
|
2204 |
msgstr ""
|
2205 |
|
2206 |
-
#:
|
|
|
|
|
2207 |
msgid ""
|
2208 |
-
"
|
2209 |
-
"
|
|
|
2210 |
msgstr ""
|
2211 |
|
2212 |
-
#:
|
2213 |
-
|
2214 |
-
|
|
|
|
|
|
|
2215 |
|
2216 |
-
#:
|
2217 |
-
msgid "
|
2218 |
msgstr ""
|
2219 |
|
2220 |
-
#:
|
2221 |
msgid ""
|
2222 |
-
"
|
2223 |
-
"
|
|
|
2224 |
msgstr ""
|
2225 |
|
2226 |
-
#:
|
2227 |
-
|
2228 |
-
msgid ""
|
2229 |
-
"The card type is invalid or does not correlate with the credit card number. "
|
2230 |
-
" Please try again or use an alternate card or other form of payment."
|
2231 |
msgstr ""
|
2232 |
|
2233 |
-
#:
|
2234 |
-
msgid "
|
2235 |
msgstr ""
|
2236 |
|
2237 |
-
#:
|
2238 |
-
|
|
|
2239 |
msgstr ""
|
2240 |
|
2241 |
-
#:
|
2242 |
-
msgid "
|
2243 |
msgstr ""
|
2244 |
|
2245 |
-
#:
|
2246 |
-
|
|
|
|
|
|
|
|
|
2247 |
msgstr ""
|
2248 |
|
2249 |
-
#:
|
2250 |
-
|
|
|
|
|
|
|
|
|
2251 |
msgstr ""
|
2252 |
|
2253 |
-
#:
|
2254 |
-
msgid "
|
|
|
|
|
|
|
2255 |
msgstr ""
|
2256 |
|
2257 |
-
#:
|
2258 |
-
msgid "
|
2259 |
msgstr ""
|
2260 |
|
2261 |
-
#:
|
2262 |
-
|
|
|
2263 |
msgstr ""
|
2264 |
|
2265 |
-
#:
|
2266 |
-
|
|
|
2267 |
msgstr ""
|
2268 |
|
2269 |
-
#:
|
|
|
|
|
|
|
2270 |
msgid ""
|
2271 |
-
"
|
2272 |
-
"
|
|
|
|
|
2273 |
msgstr ""
|
2274 |
|
2275 |
-
#:
|
|
|
|
|
|
|
2276 |
msgid ""
|
2277 |
-
"
|
2278 |
-
"of
|
2279 |
msgstr ""
|
2280 |
|
2281 |
-
#:
|
|
|
|
|
2282 |
msgid ""
|
2283 |
-
"
|
2284 |
-
"
|
2285 |
msgstr ""
|
2286 |
|
2287 |
-
#:
|
2288 |
msgid ""
|
2289 |
-
"
|
2290 |
-
"
|
|
|
2291 |
msgstr ""
|
2292 |
|
2293 |
-
#:
|
2294 |
msgid ""
|
2295 |
-
"
|
2296 |
-
"
|
|
|
|
|
2297 |
msgstr ""
|
2298 |
|
2299 |
-
|
2300 |
-
msgid "
|
2301 |
msgstr ""
|
2302 |
|
2303 |
-
#:
|
|
|
2304 |
msgid ""
|
2305 |
-
"
|
2306 |
-
"
|
2307 |
-
msgstr ""
|
2308 |
-
|
2309 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:83
|
2310 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:101
|
2311 |
-
msgid "Apple Pay"
|
2312 |
-
msgstr ""
|
2313 |
-
|
2314 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:108
|
2315 |
-
msgid "Accept Apple Pay"
|
2316 |
-
msgstr ""
|
2317 |
-
|
2318 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:115
|
2319 |
-
msgid "Allow Apple Pay on"
|
2320 |
-
msgstr ""
|
2321 |
-
|
2322 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:125
|
2323 |
-
msgid "Button Style"
|
2324 |
-
msgstr ""
|
2325 |
-
|
2326 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:128
|
2327 |
-
msgid "Black"
|
2328 |
-
msgstr ""
|
2329 |
-
|
2330 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:129
|
2331 |
-
msgid "White"
|
2332 |
-
msgstr ""
|
2333 |
-
|
2334 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:130
|
2335 |
-
msgid "White with outline"
|
2336 |
msgstr ""
|
2337 |
|
2338 |
-
#:
|
2339 |
-
|
2340 |
-
|
|
|
2341 |
msgstr ""
|
2342 |
|
2343 |
-
#:
|
2344 |
-
msgid "
|
2345 |
msgstr ""
|
2346 |
|
2347 |
-
#:
|
2348 |
-
msgid "
|
2349 |
msgstr ""
|
2350 |
|
2351 |
-
#:
|
2352 |
-
msgid "
|
|
|
|
|
2353 |
msgstr ""
|
2354 |
|
2355 |
-
#:
|
2356 |
-
|
2357 |
-
msgid "For reference, your current web root path is: %s"
|
2358 |
msgstr ""
|
2359 |
|
2360 |
-
#:
|
2361 |
-
|
2362 |
-
msgid "
|
2363 |
msgstr ""
|
2364 |
|
2365 |
-
#:
|
2366 |
-
msgid "
|
2367 |
msgstr ""
|
2368 |
|
2369 |
-
#:
|
2370 |
msgid ""
|
2371 |
-
"
|
2372 |
-
"
|
2373 |
msgstr ""
|
2374 |
|
2375 |
-
#:
|
2376 |
-
msgid "
|
2377 |
msgstr ""
|
2378 |
|
2379 |
-
#:
|
2380 |
-
#. translators: Placeholders: %1$s - plugin name, %2$s - a
|
2381 |
-
#. currency/comma-separated list of currencies, %3$s - <a> tag, %4$s - </a> tag
|
2382 |
-
msgid ""
|
2383 |
-
"Accepts payment in %1$s only. %2$sConfigure%3$s WooCommerce to accept %1$s "
|
2384 |
-
"to enable Apple Pay."
|
2385 |
-
msgid_plural ""
|
2386 |
-
"Accepts payment in one of %1$s only. %2$sConfigure%3$s WooCommerce to "
|
2387 |
-
"accept one of %1$s to enable Apple Pay."
|
2388 |
-
msgstr[0] ""
|
2389 |
-
msgstr[1] ""
|
2390 |
-
|
2391 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:334
|
2392 |
msgid ""
|
2393 |
-
"
|
2394 |
-
"
|
2395 |
-
|
2396 |
-
|
2397 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:341
|
2398 |
-
msgid "Apple Pay is disabled."
|
2399 |
-
msgstr ""
|
2400 |
-
|
2401 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:380
|
2402 |
-
msgid "Single products"
|
2403 |
-
msgstr ""
|
2404 |
-
|
2405 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-admin.php:381
|
2406 |
-
msgid "Cart"
|
2407 |
msgstr ""
|
2408 |
|
2409 |
-
#:
|
2410 |
-
msgid "
|
2411 |
msgstr ""
|
2412 |
|
2413 |
-
#:
|
2414 |
-
|
|
|
|
|
|
|
|
|
|
|
2415 |
msgstr ""
|
2416 |
|
2417 |
-
#:
|
2418 |
-
msgid "
|
2419 |
msgstr ""
|
2420 |
|
2421 |
-
#:
|
2422 |
-
|
|
|
|
|
|
|
|
|
|
|
2423 |
msgstr ""
|
2424 |
|
2425 |
-
#:
|
2426 |
-
|
2427 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:106
|
2428 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:115
|
2429 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:127
|
2430 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:171
|
2431 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:181
|
2432 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/apple-pay/class-sv-wc-payment-gateway-apple-pay-orders.php:183
|
2433 |
-
msgid "Error %d: Unable to create order. Please try again."
|
2434 |
msgstr ""
|
2435 |
|
2436 |
-
#:
|
2437 |
-
msgid "
|
2438 |
msgstr ""
|
2439 |
|
2440 |
-
#:
|
2441 |
-
msgid "
|
2442 |
msgstr ""
|
2443 |
|
2444 |
-
#:
|
2445 |
-
msgid "
|
2446 |
msgstr ""
|
2447 |
|
2448 |
-
#:
|
2449 |
-
msgid "
|
2450 |
msgstr ""
|
2451 |
|
2452 |
-
#:
|
2453 |
msgid ""
|
2454 |
-
"
|
2455 |
-
"
|
2456 |
-
msgstr ""
|
2457 |
-
|
2458 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway-direct.php:160
|
2459 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:479
|
2460 |
-
msgid "Card expiration date is invalid"
|
2461 |
msgstr ""
|
2462 |
|
2463 |
-
#:
|
2464 |
-
|
2465 |
-
|
|
|
|
|
2466 |
msgstr ""
|
2467 |
|
2468 |
-
#:
|
2469 |
-
|
2470 |
-
msgid "Card number is invalid (wrong length)"
|
2471 |
msgstr ""
|
2472 |
|
2473 |
-
#:
|
2474 |
-
|
2475 |
-
msgid "
|
2476 |
msgstr ""
|
2477 |
|
2478 |
-
#:
|
2479 |
-
|
2480 |
-
msgid "Card number is invalid"
|
2481 |
msgstr ""
|
2482 |
|
2483 |
-
#:
|
2484 |
-
|
2485 |
-
msgid "Card security code is invalid (only digits are allowed)"
|
2486 |
msgstr ""
|
2487 |
|
2488 |
-
#:
|
2489 |
-
|
2490 |
-
|
2491 |
-
msgstr ""
|
|
|
2492 |
|
2493 |
-
#:
|
2494 |
-
|
2495 |
-
|
|
|
2496 |
msgstr ""
|
2497 |
|
2498 |
-
#:
|
2499 |
-
|
2500 |
-
msgid "
|
2501 |
msgstr ""
|
2502 |
|
2503 |
-
#:
|
2504 |
-
|
2505 |
-
|
|
|
2506 |
msgstr ""
|
2507 |
|
2508 |
-
#:
|
2509 |
-
|
2510 |
-
msgid "
|
2511 |
msgstr ""
|
2512 |
|
2513 |
-
#:
|
2514 |
-
|
2515 |
-
msgid "Account Number is missing"
|
2516 |
msgstr ""
|
2517 |
|
2518 |
-
#:
|
2519 |
-
|
2520 |
-
msgid "Account Number is invalid (only digits are allowed)"
|
2521 |
msgstr ""
|
2522 |
|
2523 |
-
#:
|
2524 |
-
|
2525 |
-
msgid "Account number is invalid (must be between 5 and 17 digits)"
|
2526 |
msgstr ""
|
2527 |
|
2528 |
-
#:
|
2529 |
-
|
2530 |
-
msgid "
|
2531 |
msgstr ""
|
2532 |
|
2533 |
-
#:
|
2534 |
-
|
2535 |
-
msgid "
|
2536 |
msgstr ""
|
2537 |
|
2538 |
-
#:
|
2539 |
-
|
|
|
2540 |
msgstr ""
|
2541 |
|
2542 |
-
#:
|
2543 |
-
|
|
|
2544 |
msgstr ""
|
2545 |
|
2546 |
-
#:
|
2547 |
-
|
2548 |
-
|
2549 |
-
#. account type (savings/checking) (may or may not be available), %3$s - last
|
2550 |
-
#. four digits of the account
|
2551 |
-
msgid "%1$s Check Transaction Approved: %2$s account ending in %3$s"
|
2552 |
msgstr ""
|
2553 |
|
2554 |
-
#:
|
2555 |
-
|
2556 |
-
#. translators: Placeholders: %s - check number
|
2557 |
-
msgid "Check number %s"
|
2558 |
msgstr ""
|
2559 |
|
2560 |
-
#:
|
2561 |
-
|
2562 |
-
#. ("Test"), %3$s - transaction type (authorization/charge), %4$s - card type
|
2563 |
-
#. (mastercard, visa, ...), %5$s - last four digits of the card
|
2564 |
-
msgid "%1$s %2$s %3$s Approved: %4$s ending in %5$s"
|
2565 |
msgstr ""
|
2566 |
|
2567 |
-
#:
|
2568 |
-
|
2569 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:2567
|
2570 |
-
#. translators: Placeholders: %s - expiry date
|
2571 |
-
msgid "(expires %s)"
|
2572 |
msgstr ""
|
2573 |
|
2574 |
-
#:
|
2575 |
-
#. translators:
|
2576 |
-
msgid "
|
2577 |
msgstr ""
|
2578 |
|
2579 |
-
#:
|
2580 |
-
|
2581 |
-
#. message
|
2582 |
-
msgid "%1$s Tokenization Request Failed: %2$s"
|
2583 |
msgstr ""
|
2584 |
|
2585 |
-
#:
|
2586 |
-
|
2587 |
-
#. specific credit card, e-check or bank account
|
2588 |
-
msgid "Oops, adding your new payment method failed: %s"
|
2589 |
msgstr ""
|
2590 |
|
2591 |
-
#:
|
2592 |
-
|
2593 |
-
#. - card type (visa, mastercard, ...), %2$s - last four digits of the card,
|
2594 |
-
#. %3$s - card expiry date
|
2595 |
-
msgid "Nice! New payment method added: %1$s ending in %2$s (expires %3$s)"
|
2596 |
msgstr ""
|
2597 |
|
2598 |
-
#:
|
2599 |
-
|
2600 |
-
#. %1$s - account type (checking/savings), %2$s - last four digits of the
|
2601 |
-
#. account
|
2602 |
-
msgid "Nice! New payment method added: %1$s account ending in %2$s"
|
2603 |
msgstr ""
|
2604 |
|
2605 |
-
#:
|
2606 |
-
|
2607 |
-
#. account
|
2608 |
-
msgid "Nice! New payment method added."
|
2609 |
msgstr ""
|
2610 |
|
2611 |
-
#:
|
2612 |
-
|
2613 |
-
#. method as in a specific credit card, e-check or bank account
|
2614 |
-
msgid "%1$s - Add Payment Method for %2$s"
|
2615 |
msgstr ""
|
2616 |
|
2617 |
-
#:
|
2618 |
-
|
|
|
2619 |
msgstr ""
|
2620 |
|
2621 |
-
#:
|
2622 |
-
msgid "
|
2623 |
msgstr ""
|
2624 |
|
2625 |
-
#:
|
2626 |
-
msgid "
|
2627 |
msgstr ""
|
2628 |
|
2629 |
-
#:
|
2630 |
-
msgid "
|
2631 |
msgstr ""
|
2632 |
|
2633 |
-
#: vendor/
|
2634 |
-
msgid "
|
2635 |
msgstr ""
|
2636 |
|
2637 |
-
#: vendor/
|
2638 |
-
|
|
|
|
|
|
|
|
|
|
|
2639 |
msgstr ""
|
2640 |
|
2641 |
-
#: vendor/
|
2642 |
-
msgid "
|
2643 |
msgstr ""
|
2644 |
|
2645 |
-
#: vendor/
|
2646 |
-
msgid "
|
2647 |
msgstr ""
|
2648 |
|
2649 |
-
#: vendor/
|
2650 |
-
msgid "
|
|
|
|
|
|
|
|
|
2651 |
msgstr ""
|
2652 |
|
2653 |
-
#: vendor/
|
2654 |
-
|
2655 |
-
#. translators: Placeholders: %1$s - payment gateway title (such as
|
2656 |
-
#. Authorize.net, Braintree, etc), %2$s - payment method name (mastercard, bank
|
2657 |
-
#. account, etc), %3$s - last four digits of the card/account, %4$s -
|
2658 |
-
#. card/account expiry date
|
2659 |
-
msgid "%1$s Payment Method Saved: %2$s ending in %3$s (expires %4$s)"
|
2660 |
msgstr ""
|
2661 |
|
2662 |
-
#: vendor/
|
2663 |
-
|
2664 |
-
#. translators: Placeholders: %1$s - payment gateway title (such as CyberSouce,
|
2665 |
-
#. NETbilling, etc), %2$s - account type (checking/savings - may or may not be
|
2666 |
-
#. available), %3$s - last four digits of the account
|
2667 |
-
msgid "%1$s eCheck Payment Method Saved: %2$s account ending in %3$s"
|
2668 |
msgstr ""
|
2669 |
|
2670 |
-
#: vendor/
|
2671 |
-
|
2672 |
-
|
2673 |
-
msgid "%s Payment Method Saved"
|
2674 |
msgstr ""
|
2675 |
|
2676 |
-
#: vendor/
|
2677 |
-
|
2678 |
-
msgid "Tokenization failed. %s"
|
2679 |
msgstr ""
|
2680 |
|
2681 |
-
#: vendor/
|
2682 |
-
msgid "
|
2683 |
msgstr ""
|
2684 |
|
2685 |
-
#: vendor/
|
2686 |
-
|
|
|
2687 |
msgstr ""
|
2688 |
|
2689 |
-
#: vendor/
|
2690 |
-
|
2691 |
-
#. account
|
2692 |
-
msgid "You do not have any saved payment methods."
|
2693 |
msgstr ""
|
2694 |
|
2695 |
-
#: vendor/
|
2696 |
-
|
2697 |
-
|
2698 |
-
msgid "My Payment Methods"
|
2699 |
msgstr ""
|
2700 |
|
2701 |
-
#: vendor/
|
2702 |
-
|
2703 |
-
#. account
|
2704 |
-
msgid "Add New Payment Method"
|
2705 |
msgstr ""
|
2706 |
|
2707 |
-
#: vendor/
|
2708 |
-
|
|
|
2709 |
msgstr ""
|
2710 |
|
2711 |
-
#: vendor/
|
2712 |
-
msgid "
|
2713 |
msgstr ""
|
2714 |
|
2715 |
-
#: vendor/
|
2716 |
-
msgid "
|
2717 |
msgstr ""
|
2718 |
|
2719 |
-
#: vendor/
|
2720 |
-
msgid "
|
2721 |
msgstr ""
|
2722 |
|
2723 |
-
#: vendor/
|
2724 |
-
|
|
|
2725 |
msgstr ""
|
2726 |
|
2727 |
-
#: vendor/
|
2728 |
-
msgid "
|
2729 |
msgstr ""
|
2730 |
|
2731 |
-
#: vendor/
|
2732 |
-
|
2733 |
-
|
|
|
|
|
|
|
2734 |
|
2735 |
-
#: vendor/
|
2736 |
-
|
2737 |
-
msgid "Nickname"
|
2738 |
msgstr ""
|
2739 |
|
2740 |
-
#: vendor/
|
2741 |
-
|
|
|
2742 |
msgstr ""
|
2743 |
|
2744 |
-
#: vendor/
|
2745 |
-
|
|
|
|
|
|
|
2746 |
msgstr ""
|
2747 |
|
2748 |
-
#: vendor/
|
2749 |
-
|
2750 |
-
#. account
|
2751 |
-
msgid "Error removing payment method"
|
2752 |
msgstr ""
|
2753 |
|
2754 |
-
#: vendor/
|
2755 |
-
|
2756 |
-
#. account
|
2757 |
-
msgid "Payment method deleted."
|
2758 |
msgstr ""
|
2759 |
|
2760 |
-
#: vendor/
|
2761 |
-
msgid "
|
2762 |
msgstr ""
|
2763 |
|
2764 |
-
#: vendor/
|
2765 |
-
msgid "
|
2766 |
msgstr ""
|
2767 |
|
2768 |
-
#: vendor/
|
2769 |
-
msgid "
|
2770 |
msgstr ""
|
2771 |
|
2772 |
-
#: vendor/
|
2773 |
-
|
2774 |
-
|
|
|
|
|
|
|
2775 |
|
2776 |
-
#: vendor/
|
2777 |
-
|
2778 |
-
|
|
|
|
|
|
|
2779 |
|
2780 |
-
#: vendor/
|
2781 |
-
#. translators:
|
2782 |
-
|
2783 |
-
|
2784 |
-
msgstr ""
|
|
|
2785 |
|
2786 |
-
#: vendor/
|
2787 |
-
#. translators:
|
2788 |
-
msgid "
|
2789 |
-
|
|
|
|
|
2790 |
|
2791 |
-
#: vendor/
|
2792 |
-
#. translators:
|
2793 |
-
msgid "
|
2794 |
-
|
|
|
|
|
2795 |
|
2796 |
-
#: vendor/
|
2797 |
-
#. translators:
|
2798 |
-
|
2799 |
-
|
2800 |
-
msgstr ""
|
|
|
2801 |
|
2802 |
-
#: vendor/
|
2803 |
-
|
2804 |
-
|
|
|
|
|
|
|
2805 |
|
2806 |
-
#: vendor/
|
2807 |
-
msgid "
|
2808 |
msgstr ""
|
2809 |
|
2810 |
-
#: vendor/
|
2811 |
-
#. translators:
|
2812 |
-
msgid "
|
2813 |
msgstr ""
|
2814 |
|
2815 |
-
#: vendor/
|
2816 |
-
|
2817 |
-
#. tag
|
2818 |
-
msgid ""
|
2819 |
-
"%1$s: WooCommerce is not being forced over SSL; your customers' payment "
|
2820 |
-
"data may be at risk. %2$sVerify your site URLs here%3$s"
|
2821 |
msgstr ""
|
2822 |
|
2823 |
-
#: vendor/
|
2824 |
-
#. translators: Placeholders: %s - payment gateway name
|
2825 |
msgid ""
|
2826 |
-
"
|
2827 |
-
"
|
2828 |
-
"provider to confirm that your site can send and receive TLS 1.2 connections "
|
2829 |
-
"and request they make any necessary updates."
|
2830 |
msgstr ""
|
2831 |
|
2832 |
-
#: vendor/
|
2833 |
-
#. translators:
|
2834 |
-
#. currency/comma-separated list of currencies, %3$s - <a> tag, %4$s - </a> tag
|
2835 |
msgid ""
|
2836 |
-
"
|
2837 |
-
"
|
2838 |
msgid_plural ""
|
2839 |
-
"
|
2840 |
-
"
|
2841 |
msgstr[0] ""
|
2842 |
msgstr[1] ""
|
2843 |
|
2844 |
-
#: vendor/
|
2845 |
-
#. translators:
|
2846 |
-
#. tag, %3$s - closing </a> tag
|
2847 |
msgid ""
|
2848 |
-
"
|
2849 |
-
"
|
2850 |
-
"processing, we recommend %2$sturning off Debug Mode%3$s"
|
2851 |
msgstr ""
|
2852 |
|
2853 |
-
#: vendor/
|
2854 |
-
#. translators:
|
2855 |
-
|
2856 |
-
msgid ""
|
2857 |
-
"%1$s is inactive for subscription transactions. Please %2$senable "
|
2858 |
-
"tokenization%3$s to activate %1$s for Subscriptions."
|
2859 |
msgstr ""
|
2860 |
|
2861 |
-
#: vendor/
|
2862 |
-
#. translators:
|
2863 |
-
|
2864 |
-
msgid ""
|
2865 |
-
"%1$s is inactive for pre-order transactions. Please %2$senable "
|
2866 |
-
"tokenization%3$s to activate %1$s for Pre-Orders."
|
2867 |
msgstr ""
|
2868 |
|
2869 |
-
#: vendor/
|
2870 |
-
|
2871 |
-
"
|
2872 |
-
"renewal payments with the WooCommerce Subscriptions extension."
|
2873 |
msgstr ""
|
2874 |
|
2875 |
-
#: vendor/
|
2876 |
-
|
|
|
2877 |
msgstr ""
|
2878 |
|
2879 |
-
#: vendor/
|
2880 |
-
|
|
|
2881 |
msgstr ""
|
2882 |
|
2883 |
-
#: vendor/
|
2884 |
-
|
|
|
2885 |
msgstr ""
|
2886 |
|
2887 |
-
#: vendor/
|
2888 |
-
|
|
|
2889 |
msgstr ""
|
2890 |
|
2891 |
-
#: vendor/
|
2892 |
-
msgid "
|
2893 |
msgstr ""
|
2894 |
|
2895 |
-
#: vendor/
|
2896 |
-
msgid "
|
2897 |
msgstr ""
|
2898 |
|
2899 |
-
#: vendor/
|
2900 |
-
|
|
|
2901 |
msgstr ""
|
2902 |
|
2903 |
-
#: vendor/
|
2904 |
-
|
|
|
|
|
|
|
|
|
2905 |
msgstr ""
|
2906 |
|
2907 |
-
#: vendor/
|
2908 |
-
msgid "
|
2909 |
msgstr ""
|
2910 |
|
2911 |
-
#: vendor/
|
2912 |
-
msgid "
|
2913 |
msgstr ""
|
2914 |
|
2915 |
-
#: vendor/
|
2916 |
-
msgid "
|
2917 |
msgstr ""
|
2918 |
|
2919 |
-
#: vendor/
|
2920 |
-
msgid "
|
2921 |
msgstr ""
|
2922 |
|
2923 |
-
#: vendor/
|
2924 |
-
msgid "
|
2925 |
msgstr ""
|
2926 |
|
2927 |
-
#: vendor/
|
2928 |
-
msgid "
|
2929 |
msgstr ""
|
2930 |
|
2931 |
-
#: vendor/
|
2932 |
-
msgid "
|
2933 |
msgstr ""
|
2934 |
|
2935 |
-
#: vendor/
|
2936 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2937 |
msgstr ""
|
2938 |
|
2939 |
-
#: vendor/
|
2940 |
-
|
|
|
2941 |
msgstr ""
|
2942 |
|
2943 |
-
#: vendor/
|
2944 |
-
|
|
|
2945 |
msgstr ""
|
2946 |
|
2947 |
-
#: vendor/
|
2948 |
-
|
2949 |
-
|
|
|
|
|
|
|
2950 |
|
2951 |
-
#: vendor/
|
2952 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2953 |
msgstr ""
|
2954 |
|
2955 |
-
#: vendor/
|
2956 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2957 |
msgstr ""
|
2958 |
|
2959 |
-
#: vendor/
|
2960 |
-
msgid "
|
2961 |
msgstr ""
|
2962 |
|
2963 |
-
#: vendor/
|
2964 |
-
|
|
|
2965 |
msgstr ""
|
2966 |
|
2967 |
-
#: vendor/
|
2968 |
-
|
2969 |
-
msgid "%1$s - Order %2$s"
|
2970 |
msgstr ""
|
2971 |
|
2972 |
-
#: vendor/
|
2973 |
-
|
2974 |
-
#. Definitions: Capture as in capture funds from a credit card.
|
2975 |
-
msgid "%1$s - Capture for Order %2$s"
|
2976 |
msgstr ""
|
2977 |
|
2978 |
-
#: vendor/
|
2979 |
-
|
2980 |
-
msgid "
|
2981 |
msgstr ""
|
2982 |
|
2983 |
-
#: vendor/
|
2984 |
-
#. translators:
|
2985 |
-
|
2986 |
-
msgid "%1$s Refund in the amount of %2$s approved."
|
2987 |
msgstr ""
|
2988 |
|
2989 |
-
#: vendor/
|
2990 |
-
|
2991 |
-
#. Authorize.net, Braintree, etc), %2$s - error code, %3$s - error message
|
2992 |
-
msgid "%1$s Refund Failed: %2$s - %3$s"
|
2993 |
msgstr ""
|
2994 |
|
2995 |
-
#: vendor/
|
2996 |
-
#. translators:
|
2997 |
-
|
2998 |
-
msgid "%1$s Refund Failed: %2$s"
|
2999 |
msgstr ""
|
3000 |
|
3001 |
-
#: vendor/
|
3002 |
-
|
3003 |
-
#. Authorize.net, Braintree, etc)
|
3004 |
-
msgid "%s Order completely refunded."
|
3005 |
msgstr ""
|
3006 |
|
3007 |
-
#: vendor/
|
3008 |
-
|
3009 |
-
"
|
3010 |
-
"amount."
|
3011 |
msgstr ""
|
3012 |
|
3013 |
-
#: vendor/
|
3014 |
-
#. translators:
|
3015 |
-
|
3016 |
-
msgid "%1$s Void Failed: %2$s - %3$s"
|
3017 |
msgstr ""
|
3018 |
|
3019 |
-
#: vendor/
|
3020 |
-
#. translators:
|
3021 |
-
|
3022 |
-
msgid "%1$s Void Failed: %2$s"
|
3023 |
msgstr ""
|
3024 |
|
3025 |
-
#: vendor/
|
3026 |
-
#. translators:
|
3027 |
-
|
3028 |
-
msgid "%1$s Void in the amount of %2$s approved."
|
3029 |
msgstr ""
|
3030 |
|
3031 |
-
#: vendor/
|
3032 |
-
|
3033 |
-
#. ("Test"), %3$s - transaction type (authorization/charge)
|
3034 |
-
msgid "%1$s %2$s %3$s Approved"
|
3035 |
msgstr ""
|
3036 |
|
3037 |
-
#: vendor/
|
3038 |
-
#. translators:
|
3039 |
-
|
3040 |
-
msgid "%1$s ending in %2$s"
|
3041 |
msgstr ""
|
3042 |
|
3043 |
-
#: vendor/
|
3044 |
-
|
3045 |
-
#. (probably reason for the transaction being held for review)
|
3046 |
-
msgid "%1$s Transaction Held for Review (%2$s)"
|
3047 |
msgstr ""
|
3048 |
|
3049 |
-
#: vendor/
|
3050 |
-
#. translators:
|
3051 |
-
|
3052 |
-
msgid "%1$s Payment Failed (%2$s)"
|
3053 |
msgstr ""
|
3054 |
|
3055 |
-
#: vendor/
|
3056 |
-
|
3057 |
-
#. message/error
|
3058 |
-
msgid "%1$s Transaction Cancelled (%2$s)"
|
3059 |
msgstr ""
|
3060 |
|
3061 |
-
#: vendor/
|
3062 |
-
|
|
|
3063 |
msgstr ""
|
3064 |
|
3065 |
-
#: vendor/
|
3066 |
msgid ""
|
3067 |
-
"
|
3068 |
-
"
|
3069 |
-
"
|
3070 |
msgstr ""
|
3071 |
|
3072 |
-
#: vendor/
|
3073 |
-
msgid "
|
3074 |
msgstr ""
|
3075 |
|
3076 |
-
#: vendor/
|
3077 |
-
msgid ""
|
3078 |
-
"If the order contains exclusively virtual items, enable this to immediately "
|
3079 |
-
"charge, rather than authorize, the transaction."
|
3080 |
msgstr ""
|
3081 |
|
3082 |
-
#: vendor/
|
3083 |
-
msgid "
|
3084 |
msgstr ""
|
3085 |
|
3086 |
-
#: vendor/
|
3087 |
-
msgid "
|
3088 |
msgstr ""
|
3089 |
|
3090 |
-
#: vendor/
|
3091 |
-
msgid "
|
3092 |
msgstr ""
|
3093 |
|
3094 |
-
#: vendor/
|
3095 |
-
|
|
|
|
|
|
|
|
|
3096 |
msgstr ""
|
3097 |
|
3098 |
-
#: vendor/
|
3099 |
-
msgid "
|
3100 |
msgstr ""
|
3101 |
|
3102 |
-
#: vendor/
|
3103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3104 |
msgstr ""
|
3105 |
|
3106 |
-
#: vendor/
|
3107 |
-
|
3108 |
-
|
3109 |
-
|
|
|
3110 |
msgstr ""
|
3111 |
|
3112 |
-
#: vendor/
|
3113 |
-
|
3114 |
-
msgid ""
|
3115 |
-
"This setting %1$sdoes not%2$s change which card types the gateway will "
|
3116 |
-
"accept. Accepted cards are configured from your payment processor account."
|
3117 |
msgstr ""
|
3118 |
|
3119 |
-
#: vendor/
|
3120 |
-
|
3121 |
-
|
3122 |
-
#. https:en.wikipedia.org/wiki/Tokenization_(data_security)
|
3123 |
-
msgid "Tokenization"
|
3124 |
msgstr ""
|
3125 |
|
3126 |
-
#: vendor/
|
3127 |
-
msgid "
|
3128 |
msgstr ""
|
3129 |
|
3130 |
-
#: vendor/
|
3131 |
-
msgid "
|
3132 |
msgstr ""
|
3133 |
|
3134 |
-
#: vendor/
|
3135 |
-
msgid "
|
3136 |
msgstr ""
|
3137 |
|
3138 |
-
#: vendor/
|
3139 |
-
|
|
|
3140 |
msgstr ""
|
3141 |
|
3142 |
-
#: vendor/
|
3143 |
-
|
|
|
3144 |
msgstr ""
|
3145 |
|
3146 |
-
#: vendor/
|
3147 |
-
|
|
|
3148 |
msgstr ""
|
3149 |
|
3150 |
-
#: vendor/
|
3151 |
-
|
|
|
3152 |
msgstr ""
|
3153 |
|
3154 |
-
#: vendor/
|
3155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3156 |
msgstr ""
|
3157 |
|
3158 |
-
#: vendor/
|
3159 |
-
msgid "
|
3160 |
msgstr ""
|
3161 |
|
3162 |
-
#: vendor/
|
3163 |
-
|
3164 |
-
#. message; e.g. Order Note: [Payment method] Payment Change failed [error]
|
3165 |
-
msgid "%1$s Payment Change Failed (%2$s)"
|
3166 |
msgstr ""
|
3167 |
|
3168 |
-
#: vendor/
|
3169 |
-
msgid "
|
3170 |
msgstr ""
|
3171 |
|
3172 |
-
#: vendor/
|
3173 |
-
msgid "
|
3174 |
msgstr ""
|
3175 |
|
3176 |
-
#: vendor/
|
3177 |
-
msgid ""
|
3178 |
-
"This payment method is tied to a subscription and cannot be deleted. Please "
|
3179 |
-
"switch the subscription to another method first."
|
3180 |
msgstr ""
|
3181 |
|
3182 |
-
#: vendor/
|
3183 |
-
|
|
|
3184 |
msgstr ""
|
3185 |
|
3186 |
-
#: vendor/
|
3187 |
-
|
3188 |
-
msgid "%s is required."
|
3189 |
msgstr ""
|
3190 |
|
3191 |
-
#: vendor/
|
3192 |
-
msgid "
|
3193 |
msgstr ""
|
3194 |
|
3195 |
-
#: vendor/
|
3196 |
-
msgid "
|
3197 |
msgstr ""
|
3198 |
|
3199 |
-
#: vendor/
|
3200 |
-
msgid "
|
3201 |
msgstr ""
|
3202 |
|
3203 |
-
#: vendor/
|
3204 |
-
msgid "
|
3205 |
msgstr ""
|
3206 |
|
3207 |
-
#: vendor/
|
3208 |
-
msgid "
|
3209 |
msgstr ""
|
3210 |
|
3211 |
-
#: vendor/
|
3212 |
-
msgid "
|
3213 |
msgstr ""
|
3214 |
|
3215 |
-
#: vendor/
|
3216 |
-
msgid ""
|
3217 |
-
"This tool will test whether your server is capable of processing background "
|
3218 |
-
"jobs."
|
3219 |
msgstr ""
|
3220 |
|
3221 |
-
#: vendor/
|
3222 |
-
msgid "
|
3223 |
msgstr ""
|
3224 |
|
3225 |
-
#: vendor/
|
3226 |
msgid ""
|
3227 |
-
"
|
3228 |
-
"
|
3229 |
msgstr ""
|
3230 |
|
3231 |
-
#: woocommerce-
|
3232 |
-
|
3233 |
-
"
|
3234 |
-
"
|
3235 |
-
|
3236 |
-
|
3237 |
-
|
3238 |
-
|
|
|
|
|
|
|
3239 |
msgstr ""
|
3240 |
|
3241 |
#. Plugin URI of the plugin/theme
|
@@ -3252,239 +3250,177 @@ msgstr ""
|
|
3252 |
msgid "https://www.woocommerce.com/"
|
3253 |
msgstr ""
|
3254 |
|
3255 |
-
#: includes/Admin/Sync_Page.php:
|
3256 |
msgctxt "Delete all records"
|
3257 |
msgid "Clear history"
|
3258 |
msgstr ""
|
3259 |
|
3260 |
-
#: includes/Admin/Sync_Page.php:
|
3261 |
msgctxt "Date - Time"
|
3262 |
msgid "Time"
|
3263 |
msgstr ""
|
3264 |
|
3265 |
-
#: includes/Emails/Access_Token_Email.php:
|
3266 |
msgctxt "Email subject"
|
3267 |
msgid "[WooCommerce] There was a problem with your Square Access Token"
|
3268 |
msgstr ""
|
3269 |
|
3270 |
-
#: includes/Emails/Sync_Completed.php:
|
3271 |
msgctxt "Email subject"
|
3272 |
msgid "[WooCommerce] Square sync completed"
|
3273 |
msgstr ""
|
3274 |
|
3275 |
-
#: includes/Emails/Access_Token_Email.php:
|
3276 |
msgctxt "Email heading"
|
3277 |
msgid "There was a problem with your Square Access Token"
|
3278 |
msgstr ""
|
3279 |
|
3280 |
-
#: includes/Emails/Access_Token_Email.php:
|
3281 |
msgctxt "Square connection problems email body."
|
3282 |
msgid "Heads up! There may be a problem with your connection to Square."
|
3283 |
msgstr ""
|
3284 |
|
3285 |
-
#: includes/Emails/Sync_Completed.php:
|
3286 |
msgctxt "Email heading with merge tag placeholder"
|
3287 |
msgid "Square sync completed for {product_count}"
|
3288 |
msgstr ""
|
3289 |
|
3290 |
-
#: includes/Emails/Sync_Completed.php:
|
3291 |
msgctxt "Email body with merge tag placeholders"
|
3292 |
msgid ""
|
3293 |
"Square sync completed for {site_title} at {sync_completed_date} "
|
3294 |
"{sync_completed_time}."
|
3295 |
msgstr ""
|
3296 |
|
3297 |
-
#:
|
3298 |
-
msgctxt "
|
3299 |
-
msgid "
|
3300 |
-
msgstr ""
|
3301 |
-
|
3302 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_wpPostStore_PostStatusRegistrar.php:50
|
3303 |
-
msgctxt "post"
|
3304 |
-
msgid "In-Progress"
|
3305 |
-
msgstr ""
|
3306 |
-
|
3307 |
-
#: vendor/prospress/action-scheduler/classes/ActionScheduler_wpPostStore_PostTypeRegistrar.php:32
|
3308 |
-
msgctxt "Admin menu name"
|
3309 |
-
msgid "Scheduled Actions"
|
3310 |
-
msgstr ""
|
3311 |
-
|
3312 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:397
|
3313 |
-
msgctxt "enhanced select"
|
3314 |
-
msgid "No matches found"
|
3315 |
-
msgstr ""
|
3316 |
-
|
3317 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:398
|
3318 |
-
msgctxt "enhanced select"
|
3319 |
-
msgid "Loading failed"
|
3320 |
-
msgstr ""
|
3321 |
-
|
3322 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:399
|
3323 |
-
msgctxt "enhanced select"
|
3324 |
-
msgid "Please enter 1 or more characters"
|
3325 |
-
msgstr ""
|
3326 |
-
|
3327 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:400
|
3328 |
-
msgctxt "enhanced select"
|
3329 |
-
msgid "Please enter %qty% or more characters"
|
3330 |
-
msgstr ""
|
3331 |
-
|
3332 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:401
|
3333 |
-
msgctxt "enhanced select"
|
3334 |
-
msgid "Please delete 1 character"
|
3335 |
-
msgstr ""
|
3336 |
-
|
3337 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:402
|
3338 |
-
msgctxt "enhanced select"
|
3339 |
-
msgid "Please delete %qty% characters"
|
3340 |
-
msgstr ""
|
3341 |
-
|
3342 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:403
|
3343 |
-
msgctxt "enhanced select"
|
3344 |
-
msgid "You can only select 1 item"
|
3345 |
-
msgstr ""
|
3346 |
-
|
3347 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:404
|
3348 |
-
msgctxt "enhanced select"
|
3349 |
-
msgid "You can only select %qty% items"
|
3350 |
-
msgstr ""
|
3351 |
-
|
3352 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:405
|
3353 |
-
msgctxt "enhanced select"
|
3354 |
-
msgid "Loading more results…"
|
3355 |
-
msgstr ""
|
3356 |
-
|
3357 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/admin/abstract-sv-wc-plugin-admin-setup-wizard.php:406
|
3358 |
-
msgctxt "enhanced select"
|
3359 |
-
msgid "Searching…"
|
3360 |
-
msgstr ""
|
3361 |
-
|
3362 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-helper.php:408
|
3363 |
-
msgctxt "coordinating conjunction for a list of items: a, b, and c"
|
3364 |
-
msgid "and"
|
3365 |
-
msgstr ""
|
3366 |
-
|
3367 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/class-sv-wc-plugin.php:534
|
3368 |
-
msgctxt "noun"
|
3369 |
-
msgid "Support"
|
3370 |
msgstr ""
|
3371 |
|
3372 |
-
#:
|
3373 |
-
msgctxt "
|
3374 |
-
msgid "
|
3375 |
msgstr ""
|
3376 |
|
3377 |
-
#:
|
3378 |
-
#:
|
3379 |
msgctxt "noun, software environment"
|
3380 |
msgid "Test"
|
3381 |
msgstr ""
|
3382 |
|
3383 |
-
#:
|
3384 |
-
#:
|
3385 |
-
#:
|
3386 |
msgctxt "credit card transaction type"
|
3387 |
msgid "Authorization"
|
3388 |
msgstr ""
|
3389 |
|
3390 |
-
#:
|
3391 |
-
#:
|
3392 |
-
#:
|
3393 |
msgctxt "noun, credit card transaction type"
|
3394 |
msgid "Charge"
|
3395 |
msgstr ""
|
3396 |
|
3397 |
-
#:
|
3398 |
-
msgctxt "
|
3399 |
-
|
|
|
|
|
3400 |
msgstr ""
|
3401 |
|
3402 |
-
#:
|
3403 |
-
#:
|
3404 |
msgctxt "credit card type"
|
3405 |
msgid "Visa"
|
3406 |
msgstr ""
|
3407 |
|
3408 |
-
#:
|
3409 |
-
#:
|
3410 |
msgctxt "credit card type"
|
3411 |
msgid "MasterCard"
|
3412 |
msgstr ""
|
3413 |
|
3414 |
-
#:
|
3415 |
-
#:
|
3416 |
msgctxt "credit card type"
|
3417 |
msgid "American Express"
|
3418 |
msgstr ""
|
3419 |
|
3420 |
-
#:
|
|
|
3421 |
msgctxt "credit card type"
|
3422 |
-
msgid "
|
3423 |
msgstr ""
|
3424 |
|
3425 |
-
#:
|
3426 |
-
#: vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/class-sv-wc-payment-gateway.php:3288
|
3427 |
msgctxt "credit card type"
|
3428 |
-
msgid "
|
3429 |
msgstr ""
|
3430 |
|
3431 |
-
#:
|
3432 |
-
#:
|
3433 |
msgctxt "credit card type"
|
3434 |
msgid "JCB"
|
3435 |
msgstr ""
|
3436 |
|
3437 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
3438 |
msgctxt "credit card type"
|
3439 |
msgid "CarteBleue"
|
3440 |
msgstr ""
|
3441 |
|
3442 |
-
#:
|
3443 |
msgctxt "credit card type"
|
3444 |
msgid "Maestro"
|
3445 |
msgstr ""
|
3446 |
|
3447 |
-
#:
|
3448 |
msgctxt "credit card type"
|
3449 |
msgid "Laser"
|
3450 |
msgstr ""
|
3451 |
|
3452 |
-
#:
|
3453 |
-
msgctxt "
|
3454 |
-
msgid "
|
3455 |
msgstr ""
|
3456 |
|
3457 |
-
#:
|
3458 |
-
|
3459 |
-
|
3460 |
-
msgid "Checking"
|
3461 |
msgstr ""
|
3462 |
|
3463 |
-
#:
|
3464 |
-
|
3465 |
-
|
3466 |
-
msgid "Savings"
|
3467 |
msgstr ""
|
3468 |
|
3469 |
-
#:
|
3470 |
-
msgctxt "
|
3471 |
-
msgid "
|
3472 |
msgstr ""
|
3473 |
|
3474 |
-
#:
|
3475 |
-
|
3476 |
-
|
|
|
3477 |
msgstr ""
|
3478 |
|
3479 |
-
#: vendor/
|
3480 |
-
msgctxt ""
|
3481 |
-
|
3482 |
-
"or completed"
|
3483 |
-
msgid "or"
|
3484 |
msgstr ""
|
3485 |
|
3486 |
-
#: vendor/
|
3487 |
-
|
3488 |
-
|
3489 |
-
|
|
|
|
|
|
|
|
|
3490 |
msgstr ""
|
2 |
# This file is distributed under the GNU General Public License v3.0.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WooCommerce Square 3.0.0\n"
|
6 |
"Report-Msgid-Bugs-To: "
|
7 |
"https://wordpress.org/support/plugin/woocommerce-square\n"
|
8 |
+
"POT-Creation-Date: 2022-05-05 00:39:11+00:00\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=utf-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
14 |
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
|
15 |
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
16 |
|
17 |
+
#: includes/AJAX.php:75
|
18 |
msgid "Please mark product as un-synced and save, then synced again."
|
19 |
msgstr ""
|
20 |
|
21 |
+
#: includes/AJAX.php:88
|
22 |
#. translators: Placeholders: %1$s = error message, %2$s = help text
|
23 |
msgid "Unable to fetch inventory: %1$s. %2$s"
|
24 |
msgstr ""
|
25 |
|
26 |
+
#: includes/AJAX.php:93
|
27 |
#. translators: Placeholders: %s = help text
|
28 |
msgid "Error finding item in Square. %s"
|
29 |
msgstr ""
|
30 |
|
31 |
+
#: includes/AJAX.php:111
|
32 |
msgid "Could not start import. Please try again."
|
33 |
msgstr ""
|
34 |
|
35 |
+
#: includes/AJAX.php:114
|
36 |
msgid ""
|
37 |
"Your products are being imported in the background! This may take some time "
|
38 |
"to complete."
|
39 |
msgstr ""
|
40 |
|
41 |
+
#: includes/AJAX.php:160
|
42 |
msgid "Could not delete records."
|
43 |
msgstr ""
|
44 |
|
45 |
+
#: includes/AJAX.php:168
|
46 |
msgid "Could not delete record."
|
47 |
msgstr ""
|
48 |
|
49 |
+
#: includes/AJAX.php:178
|
50 |
msgid "Could not resolve record."
|
51 |
msgstr ""
|
52 |
|
53 |
+
#: includes/AJAX.php:190
|
54 |
msgid "Could not unsync product."
|
55 |
msgstr ""
|
56 |
|
57 |
+
#: includes/AJAX.php:202
|
58 |
#. translators: Placeholder: %s - error message
|
59 |
msgid "An error occurred. %s"
|
60 |
msgstr ""
|
61 |
|
62 |
+
#: includes/AJAX.php:247
|
63 |
#. translators: Placeholder: %s - sync job ID
|
64 |
msgid "No sync job in progress found %s"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: includes/AJAX.php:285
|
68 |
msgid "Stock must be fetched from Square before editing stock quantity"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: includes/Admin/Privacy.php:43 includes/Admin/Settings_Page.php:54
|
72 |
+
#: includes/Gateway.php:82 includes/Settings.php:221 includes/Settings.php:755
|
73 |
msgid "Square"
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: includes/Admin/Privacy.php:45
|
77 |
msgid "WooCommerce Square Customer Data"
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: includes/Admin/Privacy.php:59
|
81 |
#. translators: Placeholder: %1$s - <a> tag, %2$s - </a> tag
|
82 |
msgid ""
|
83 |
"By using this extension, you may be storing personal data or sharing data "
|
85 |
"what you may want to include in your privacy policy.%2$s"
|
86 |
msgstr ""
|
87 |
|
88 |
+
#: includes/Admin/Privacy.php:91
|
89 |
msgid "Square User Data Erased."
|
90 |
msgstr ""
|
91 |
|
92 |
+
#: includes/Admin/Settings_Page.php:144
|
93 |
msgid "Settings"
|
94 |
msgstr ""
|
95 |
|
96 |
+
#: includes/Admin/Settings_Page.php:145 includes/Admin/Sync_Page.php:49
|
97 |
msgid "Update"
|
98 |
msgstr ""
|
99 |
|
100 |
+
#: includes/Admin/Settings_Page.php:172
|
101 |
msgid "Import Products From Square"
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: includes/Admin/Settings_Page.php:174 includes/Admin/Sync_Page.php:358
|
105 |
msgid "Close modal window"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: includes/Admin/Settings_Page.php:179
|
109 |
#. translators: Placeholders: %1$s - <strong>, %2%s - </strong>
|
110 |
msgid ""
|
111 |
"You are about to import all new products, variations and categories from "
|
114 |
"imports, these will be ignored in the import."
|
115 |
msgstr ""
|
116 |
|
117 |
+
#: includes/Admin/Settings_Page.php:181
|
118 |
msgid "Do you wish to import existing product updates from Square?"
|
119 |
msgstr ""
|
120 |
|
121 |
+
#: includes/Admin/Settings_Page.php:183
|
122 |
#. translators: Placeholders: %1$s - <a> tag linking to WooCommerce Square
|
123 |
#. docs, %2%s - closing </a> tag
|
124 |
msgid ""
|
126 |
"information from Square. %1$sView Documentation%2$s."
|
127 |
msgstr ""
|
128 |
|
129 |
+
#: includes/Admin/Settings_Page.php:184
|
130 |
msgid "Update existing products during import."
|
131 |
msgstr ""
|
132 |
|
133 |
+
#: includes/Admin/Settings_Page.php:188 includes/Admin/Sync_Page.php:392
|
134 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:41
|
135 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:203
|
136 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:133
|
137 |
msgid "Cancel"
|
138 |
msgstr ""
|
139 |
|
140 |
+
#: includes/Admin/Settings_Page.php:189 includes/Settings.php:242
|
141 |
msgid "Import Products"
|
142 |
msgstr ""
|
143 |
|
144 |
+
#: includes/Admin/Sync_Page.php:53
|
145 |
msgid "Sync records"
|
146 |
msgstr ""
|
147 |
|
148 |
+
#: includes/Admin/Sync_Page.php:79
|
149 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
150 |
#. $4%s - closing </strong> HTML tag
|
151 |
msgid ""
|
154 |
"description, category, inventory%4$s."
|
155 |
msgstr ""
|
156 |
|
157 |
+
#: includes/Admin/Sync_Page.php:93
|
158 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
159 |
#. </strong> HTML tag
|
160 |
msgid ""
|
162 |
"set in WooCommerce."
|
163 |
msgstr ""
|
164 |
|
165 |
+
#: includes/Admin/Sync_Page.php:108
|
166 |
#. translators: Placeholders: %1$s, %3$s - opening <strong> HTML tag, %2$s,
|
167 |
#. %4$s - closing </strong> HTML tag
|
168 |
msgid ""
|
171 |
"price, inventory, category, image%4$s."
|
172 |
msgstr ""
|
173 |
|
174 |
+
#: includes/Admin/Sync_Page.php:125
|
175 |
#. translators: Placeholders: %1$s - opening <strong> HTML tag, %2$s closing
|
176 |
#. </strong> HTML tag
|
177 |
msgid ""
|
179 |
"Square and WooCommerce."
|
180 |
msgstr ""
|
181 |
|
182 |
+
#: includes/Admin/Sync_Page.php:160
|
183 |
msgid "Please connect to Square to enable product sync."
|
184 |
msgstr ""
|
185 |
|
186 |
+
#: includes/Admin/Sync_Page.php:162
|
187 |
msgid "Please set the business location to enable product sync."
|
188 |
msgstr ""
|
189 |
|
190 |
+
#: includes/Admin/Sync_Page.php:164
|
191 |
msgid "There are currently no products marked to be synced with Square."
|
192 |
msgstr ""
|
193 |
|
194 |
+
#: includes/Admin/Sync_Page.php:166
|
195 |
msgid "A sync is currently in progress. Please try again later."
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: includes/Admin/Sync_Page.php:171
|
199 |
#. translators: Placeholder: %s - reason text
|
200 |
msgid "Product sync between WooCommerce and Square is currently unavailable. %s"
|
201 |
msgstr ""
|
202 |
|
203 |
+
#: includes/Admin/Sync_Page.php:178
|
204 |
msgid "Synced products"
|
205 |
msgstr ""
|
206 |
|
207 |
+
#: includes/Admin/Sync_Page.php:179
|
208 |
msgid "Latest sync"
|
209 |
msgstr ""
|
210 |
|
211 |
+
#: includes/Admin/Sync_Page.php:180
|
212 |
msgid "Next sync"
|
213 |
msgstr ""
|
214 |
|
215 |
+
#: includes/Admin/Sync_Page.php:181 includes/Admin/Sync_Page.php:294
|
216 |
+
#: includes/Admin/Sync_Page.php:335
|
217 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:315
|
218 |
msgid "Actions"
|
219 |
msgstr ""
|
220 |
|
221 |
+
#: includes/Admin/Sync_Page.php:191 includes/Emails/Sync_Completed.php:195
|
222 |
#. translators: Placeholder: %d number of products synced with Square
|
223 |
#. translators: Placeholder: %d products count
|
224 |
msgid "%d product"
|
226 |
msgstr[0] ""
|
227 |
msgstr[1] ""
|
228 |
|
229 |
+
#: includes/Admin/Sync_Page.php:209
|
230 |
msgid "Importing now…"
|
231 |
msgstr ""
|
232 |
|
233 |
+
#: includes/Admin/Sync_Page.php:211
|
234 |
msgid "Syncing now…"
|
235 |
msgstr ""
|
236 |
|
237 |
+
#: includes/Admin/Sync_Page.php:226
|
238 |
msgid "Not synced yet."
|
239 |
msgstr ""
|
240 |
|
241 |
+
#: includes/Admin/Sync_Page.php:258
|
242 |
msgid "Sync now"
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: includes/Admin/Sync_Page.php:292 includes/Admin/Sync_Page.php:333
|
246 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:144
|
247 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:97
|
248 |
msgid "Status"
|
249 |
msgstr ""
|
250 |
|
251 |
+
#: includes/Admin/Sync_Page.php:293 includes/Admin/Sync_Page.php:334
|
252 |
msgid "Message"
|
253 |
msgstr ""
|
254 |
|
255 |
+
#: includes/Admin/Sync_Page.php:324
|
256 |
msgid "No records found."
|
257 |
msgstr ""
|
258 |
|
259 |
+
#: includes/Admin/Sync_Page.php:356
|
260 |
msgid "Sync products with Square"
|
261 |
msgstr ""
|
262 |
|
263 |
+
#: includes/Admin/Sync_Page.php:366
|
264 |
msgid ""
|
265 |
"If a match is found in Square, product data in WooCommerce will be "
|
266 |
"overwritten with Square data."
|
267 |
msgstr ""
|
268 |
|
269 |
+
#: includes/Admin/Sync_Page.php:368
|
270 |
msgid ""
|
271 |
"If a match is found in WooCommerce, product data in Square will be "
|
272 |
"overwritten with WooCommerce data."
|
273 |
msgstr ""
|
274 |
|
275 |
+
#: includes/Admin/Sync_Page.php:372
|
276 |
msgid ""
|
277 |
"If a match is not found in Square, the product will be hidden from the "
|
278 |
"catalog in WooCommerce."
|
279 |
msgstr ""
|
280 |
|
281 |
+
#: includes/Admin/Sync_Page.php:374
|
282 |
msgid "If a match is not found in Square, the product will be skipped in the sync."
|
283 |
msgstr ""
|
284 |
|
285 |
+
#: includes/Admin/Sync_Page.php:377
|
286 |
msgid "If a match is not found, a new product will be created in Square."
|
287 |
msgstr ""
|
288 |
|
289 |
+
#: includes/Admin/Sync_Page.php:384
|
290 |
#. translators: Placeholders: %1$s - the system of record name (e.g. Square or
|
291 |
#. WooCommerce), %3%s - unordered HTML list of additional information item(s)
|
292 |
msgid ""
|
294 |
"For all products synced with Square: %2$s"
|
295 |
msgstr ""
|
296 |
|
297 |
+
#: includes/Admin/Sync_Page.php:393
|
298 |
msgid "Start sync"
|
299 |
msgstr ""
|
300 |
|
301 |
+
#: includes/Admin.php:143 includes/Handlers/Products.php:175
|
302 |
msgid "Synced with Square"
|
303 |
msgstr ""
|
304 |
|
310 |
msgid "Fetch stock from Square"
|
311 |
msgstr ""
|
312 |
|
313 |
+
#: includes/Admin.php:191 includes/Sync/Records/Record.php:208
|
314 |
msgid "Resolved"
|
315 |
msgstr ""
|
316 |
|
317 |
+
#: includes/Admin.php:192
|
318 |
msgid "No records found"
|
319 |
msgstr ""
|
320 |
|
321 |
+
#: includes/Admin.php:193
|
322 |
msgid "Skipped"
|
323 |
msgstr ""
|
324 |
|
325 |
+
#: includes/Admin.php:194
|
326 |
msgid "Updated"
|
327 |
msgstr ""
|
328 |
|
329 |
+
#: includes/Admin.php:195
|
330 |
msgid "Imported"
|
331 |
msgstr ""
|
332 |
|
333 |
+
#: includes/Admin.php:197
|
334 |
msgid "Enable to fetch inventory changes from Square"
|
335 |
msgstr ""
|
336 |
|
337 |
+
#: includes/Admin.php:198
|
338 |
msgid "Enable to push inventory changes to Square"
|
339 |
msgstr ""
|
340 |
|
341 |
+
#: includes/Admin.php:201 includes/Settings.php:231
|
342 |
msgid "Inventory is fetched from Square periodically and updated in WooCommerce"
|
343 |
msgstr ""
|
344 |
|
345 |
+
#: includes/Admin.php:204
|
346 |
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
347 |
msgid ""
|
348 |
"Inventory is %1$salways fetched from Square%2$s periodically to account for "
|
349 |
"sales from other channels."
|
350 |
msgstr ""
|
351 |
|
352 |
+
#: includes/Emails/Access_Token_Email.php:43
|
353 |
msgid "Square Access Token problems"
|
354 |
msgstr ""
|
355 |
|
356 |
+
#: includes/Emails/Access_Token_Email.php:44
|
357 |
msgid "This email is sent when problems with Access Token are encountered"
|
358 |
msgstr ""
|
359 |
|
360 |
+
#: includes/Emails/Access_Token_Email.php:97
|
361 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
362 |
#. </a> HTML link tag
|
363 |
msgid ""
|
365 |
"re-connect your site%2$s."
|
366 |
msgstr ""
|
367 |
|
368 |
+
#: includes/Emails/Access_Token_Email.php:105
|
369 |
+
#: includes/Emails/Sync_Completed.php:88
|
370 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
371 |
#. </a> HTML link tag
|
372 |
msgid "%1$sInspect status logs%2$s"
|
373 |
msgstr ""
|
374 |
|
375 |
+
#: includes/Emails/Access_Token_Email.php:111
|
376 |
msgid ""
|
377 |
"In order to continue accepting payments, please disconnect and re-connect "
|
378 |
"your site at "
|
395 |
"%s"
|
396 |
msgstr ""
|
397 |
|
398 |
+
#: includes/Emails/Sync_Completed.php:33
|
399 |
msgid "Square sync completed"
|
400 |
msgstr ""
|
401 |
|
402 |
+
#: includes/Emails/Sync_Completed.php:34
|
403 |
msgid ""
|
404 |
"This email is sent once a manual sync has been completed between "
|
405 |
"WooCommerce and Square"
|
406 |
msgstr ""
|
407 |
|
408 |
+
#: includes/Emails/Sync_Completed.php:58
|
409 |
msgid "Square sync failed"
|
410 |
msgstr ""
|
411 |
|
412 |
+
#: includes/Emails/Sync_Completed.php:95
|
413 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
414 |
#. </a> HTML link tag
|
415 |
msgid "%1$sEnable logging%2$s"
|
416 |
msgstr ""
|
417 |
|
418 |
+
#: includes/Emails/Sync_Completed.php:103
|
419 |
#. translators: Placeholders: %1$s - opening <a> HTML link tag, %2$s - closing
|
420 |
#. </a> HTML link tag, %3$s - additional action
|
421 |
msgid "The sync job has failed. %1$sClick for more details%2$s, or %3$s."
|
422 |
msgstr ""
|
423 |
|
424 |
+
#: includes/Emails/Sync_Completed.php:112
|
425 |
msgid "Inspect status logs"
|
426 |
msgstr ""
|
427 |
|
428 |
+
#: includes/Emails/Sync_Completed.php:114 includes/Settings.php:267
|
429 |
msgid "Enable Logging"
|
430 |
msgstr ""
|
431 |
|
432 |
+
#: includes/Emails/Sync_Completed.php:119
|
433 |
#. translators: Placeholders: %s - additional action
|
434 |
msgid "The sync job has failed. Check sync records, or %s."
|
435 |
msgstr ""
|
436 |
|
437 |
+
#: includes/Framework/Lifecycle.php:303 includes/Lifecycle.php:183
|
438 |
+
msgid "Awesome"
|
|
|
|
|
439 |
msgstr ""
|
440 |
|
441 |
+
#: includes/Framework/Lifecycle.php:304 includes/Lifecycle.php:186
|
442 |
+
msgid "Fantastic"
|
|
|
443 |
msgstr ""
|
444 |
|
445 |
+
#: includes/Framework/Lifecycle.php:305
|
446 |
+
msgid "Cowabunga"
|
|
|
|
|
|
|
|
|
|
|
447 |
msgstr ""
|
448 |
|
449 |
+
#: includes/Framework/Lifecycle.php:306 includes/Lifecycle.php:184
|
450 |
+
msgid "Congratulations"
|
|
|
451 |
msgstr ""
|
452 |
|
453 |
+
#: includes/Framework/Lifecycle.php:307
|
454 |
+
msgid "Hot dog"
|
|
|
|
|
|
|
|
|
|
|
455 |
msgstr ""
|
456 |
|
457 |
+
#: includes/Framework/Lifecycle.php:314 includes/Lifecycle.php:193
|
458 |
+
#. translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a>
|
459 |
+
#. tag, %4$s - <a> tag, %5$s - </a> tag
|
460 |
msgid ""
|
461 |
+
"Are you having a great experience with %1$s so far? Please consider "
|
462 |
+
"%2$sleaving a review%3$s! If things aren't going quite as expected, we're "
|
463 |
+
"happy to help -- please %4$sreach out to our support team%5$s."
|
464 |
msgstr ""
|
465 |
|
466 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:100
|
467 |
+
msgid "Are you sure you wish to process this capture? The action cannot be undone."
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
msgstr ""
|
469 |
|
470 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:103
|
471 |
+
msgid ""
|
472 |
+
"Something went wrong, and the capture could no be completed. Please try "
|
473 |
+
"again."
|
474 |
msgstr ""
|
475 |
|
476 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:147
|
477 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:265
|
478 |
+
msgid "Capture Charge"
|
479 |
msgstr ""
|
480 |
|
481 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:255
|
482 |
+
msgid "This charge has been fully captured."
|
|
|
|
|
|
|
483 |
msgstr ""
|
484 |
|
485 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:257
|
486 |
+
msgid "This charge can no longer be captured."
|
|
|
487 |
msgstr ""
|
488 |
|
489 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php:259
|
490 |
+
msgid "This charge cannot be captured."
|
|
|
491 |
msgstr ""
|
492 |
|
493 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:71
|
494 |
+
msgid "Are you sure you want to remove this token?"
|
495 |
msgstr ""
|
496 |
|
497 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:81
|
498 |
+
msgid "Invalid token data"
|
|
|
499 |
msgstr ""
|
500 |
|
501 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:85
|
502 |
+
msgid "An error occurred. Please try again."
|
|
|
503 |
msgstr ""
|
504 |
|
505 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:433
|
506 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_User_Handler.php:279
|
507 |
+
msgid "(%s)"
|
508 |
msgstr ""
|
509 |
|
510 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:463
|
511 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:537
|
512 |
+
msgid "Default"
|
513 |
msgstr ""
|
514 |
|
515 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:499
|
516 |
+
msgid "Token ID"
|
517 |
msgstr ""
|
518 |
|
519 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:504
|
520 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:274
|
521 |
+
msgid "Card Type"
|
522 |
msgstr ""
|
523 |
|
524 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:509
|
525 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:166
|
526 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:272
|
527 |
+
msgid "Last Four"
|
528 |
msgstr ""
|
529 |
|
530 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:516
|
531 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:286
|
532 |
+
msgid "Expiration (MM/YY)"
|
533 |
msgstr ""
|
534 |
|
535 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:614
|
536 |
+
msgid "Refresh"
|
537 |
msgstr ""
|
538 |
|
539 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:616
|
540 |
+
msgid "Add New"
|
|
|
|
|
541 |
msgstr ""
|
542 |
|
543 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:619
|
544 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:632
|
545 |
+
msgid "Save"
|
|
|
546 |
msgstr ""
|
547 |
|
548 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php:642
|
549 |
+
msgid "Remove"
|
|
|
550 |
msgstr ""
|
551 |
|
552 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_User_Handler.php:198
|
553 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:35
|
554 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:36
|
555 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:183
|
556 |
+
msgid "%s Payment Tokens"
|
557 |
msgstr ""
|
558 |
|
559 |
+
#: includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_User_Handler.php:276
|
560 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:640
|
561 |
+
msgid "Customer ID"
|
562 |
msgstr ""
|
563 |
|
564 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:7
|
565 |
+
msgid "This section contains configuration settings for this gateway."
|
|
|
566 |
msgstr ""
|
567 |
|
568 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:28
|
569 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1195
|
570 |
+
#. translators: environment as in a software environment (test/production)
|
571 |
+
msgid "Environment"
|
572 |
msgstr ""
|
573 |
|
574 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:29
|
575 |
+
msgid "The transaction environment for this gateway."
|
576 |
msgstr ""
|
577 |
|
578 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:36
|
579 |
+
msgid "Tokenization Enabled"
|
|
|
580 |
msgstr ""
|
581 |
|
582 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:37
|
583 |
+
msgid "Displays whether or not tokenization is enabled for this gateway."
|
|
|
|
|
|
|
584 |
msgstr ""
|
585 |
|
586 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:50
|
587 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1125
|
588 |
+
#: includes/Gateway.php:645
|
589 |
msgid "Debug Mode"
|
590 |
msgstr ""
|
591 |
|
592 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:51
|
593 |
+
msgid "Displays whether or not debug logging is enabled for this gateway."
|
|
|
|
|
|
|
|
|
594 |
msgstr ""
|
595 |
|
596 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:54
|
597 |
+
msgid "Display at Checkout & Log"
|
|
|
|
|
598 |
msgstr ""
|
599 |
|
600 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:56
|
601 |
+
msgid "Display at Checkout"
|
|
|
602 |
msgstr ""
|
603 |
|
604 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:58
|
605 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1133
|
606 |
+
#: includes/Gateway.php:653
|
607 |
msgid "Save to Log"
|
608 |
msgstr ""
|
609 |
|
610 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php:60
|
611 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1131
|
612 |
+
#: includes/Gateway.php:651
|
613 |
+
msgid "Off"
|
614 |
msgstr ""
|
615 |
|
616 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:5
|
617 |
+
msgid "Authorization total"
|
618 |
msgstr ""
|
619 |
|
620 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:9
|
621 |
+
msgid "Amount already captured"
|
|
|
|
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:15
|
625 |
+
msgid "Remaining order total"
|
626 |
msgstr ""
|
627 |
|
628 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:21
|
629 |
+
msgid "Capture amount"
|
630 |
msgstr ""
|
631 |
|
632 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:28
|
633 |
+
msgid "Comment (optional):"
|
|
|
|
|
|
|
|
|
634 |
msgstr ""
|
635 |
|
636 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php:40
|
637 |
+
msgid "Capture %s"
|
638 |
msgstr ""
|
639 |
|
640 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor-token.php:23
|
641 |
+
msgid "-- Select an option --"
|
642 |
msgstr ""
|
643 |
|
644 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor.php:34
|
645 |
+
msgid "No saved payment tokens"
|
|
|
|
|
|
|
646 |
msgstr ""
|
647 |
|
648 |
+
#: includes/Framework/PaymentGateway/Admin/views/html-user-profile-field-customer-id.php:5
|
649 |
+
msgid "The gateway customer ID for the user. Only edit this if necessary."
|
650 |
msgstr ""
|
651 |
|
652 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:33
|
653 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php:118
|
654 |
+
msgid "An error occurred, please try again or try an alternate form of payment"
|
655 |
msgstr ""
|
656 |
|
657 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:34
|
658 |
+
msgid ""
|
659 |
+
"We cannot process your order with the payment information that you "
|
660 |
+
"provided. Please use a different payment account or an alternate payment "
|
661 |
+
"method."
|
662 |
msgstr ""
|
663 |
|
664 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:35
|
665 |
+
msgid ""
|
666 |
+
"This order is being placed on hold for review. Please contact us to "
|
667 |
+
"complete the transaction."
|
668 |
msgstr ""
|
669 |
|
670 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:40
|
671 |
+
msgid ""
|
672 |
+
"This order is being placed on hold for review due to an incorrect card "
|
673 |
+
"verification number. You may contact the store to complete the transaction."
|
674 |
msgstr ""
|
675 |
|
676 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:41
|
677 |
+
msgid "The card verification number is invalid, please try again."
|
678 |
msgstr ""
|
679 |
|
680 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:42
|
681 |
+
msgid "Please enter your card verification number and try again."
|
682 |
+
msgstr ""
|
683 |
+
|
684 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:45
|
685 |
msgid ""
|
686 |
+
"That card type is not accepted, please use an alternate card or other form "
|
687 |
+
"of payment."
|
688 |
msgstr ""
|
689 |
|
690 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:46
|
691 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:50
|
692 |
+
msgid ""
|
693 |
+
"The card type is invalid or does not correlate with the credit card number. "
|
694 |
+
" Please try again or use an alternate card or other form of payment."
|
695 |
msgstr ""
|
696 |
|
697 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:47
|
698 |
+
msgid "Please select the card type and try again."
|
699 |
msgstr ""
|
700 |
|
701 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:51
|
702 |
+
msgid "The card number is invalid, please re-enter and try again."
|
703 |
msgstr ""
|
704 |
|
705 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:52
|
706 |
+
msgid "Please enter your card number and try again."
|
707 |
msgstr ""
|
708 |
|
709 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:55
|
710 |
+
msgid "The card expiration date is invalid, please re-enter and try again."
|
711 |
msgstr ""
|
712 |
|
713 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:56
|
714 |
+
msgid "The card expiration month is invalid, please re-enter and try again."
|
715 |
msgstr ""
|
716 |
|
717 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:57
|
718 |
+
msgid "The card expiration year is invalid, please re-enter and try again."
|
719 |
msgstr ""
|
720 |
|
721 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:58
|
722 |
+
msgid "Please enter your card expiration date and try again."
|
723 |
msgstr ""
|
724 |
|
725 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:61
|
726 |
+
msgid "The bank routing number is invalid, please re-enter and try again."
|
727 |
msgstr ""
|
728 |
|
729 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:62
|
730 |
+
msgid "The bank account number is invalid, please re-enter and try again."
|
731 |
msgstr ""
|
732 |
|
733 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:65
|
|
|
734 |
msgid ""
|
735 |
+
"The provided card is expired, please use an alternate card or other form of "
|
736 |
+
"payment."
|
737 |
msgstr ""
|
738 |
|
739 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:66
|
740 |
+
msgid ""
|
741 |
+
"The provided card was declined, please use an alternate card or other form "
|
742 |
+
"of payment."
|
743 |
msgstr ""
|
744 |
|
745 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:67
|
|
|
746 |
msgid ""
|
747 |
+
"Insufficient funds in account, please use an alternate card or other form "
|
748 |
+
"of payment."
|
749 |
msgstr ""
|
750 |
|
751 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:68
|
|
|
752 |
msgid ""
|
753 |
+
"The card is inactivate or not authorized for card-not-present transactions, "
|
754 |
+
"please use an alternate card or other form of payment."
|
|
|
755 |
msgstr ""
|
756 |
|
757 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:69
|
758 |
+
msgid ""
|
759 |
+
"The credit limit for the card has been reached, please use an alternate "
|
760 |
+
"card or other form of payment."
|
761 |
msgstr ""
|
762 |
|
763 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:70
|
764 |
+
msgid "The card verification number does not match. Please re-enter and try again."
|
765 |
msgstr ""
|
766 |
|
767 |
+
#: includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php:71
|
768 |
+
msgid ""
|
769 |
+
"The provided address does not match the billing address for cardholder. "
|
770 |
+
"Please verify the address and try again."
|
771 |
msgstr ""
|
772 |
|
773 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:102
|
774 |
+
msgid "Invalid payment response data"
|
775 |
msgstr ""
|
776 |
|
777 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:105
|
778 |
+
msgid ""
|
779 |
+
"Payment Response:\n"
|
780 |
+
" %s"
|
781 |
msgstr ""
|
782 |
|
783 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:113
|
784 |
+
msgid "Apple Pay payment authorized."
|
785 |
msgstr ""
|
786 |
|
787 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:129
|
788 |
+
msgid "Gateway processing error."
|
789 |
msgstr ""
|
790 |
|
791 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:146
|
792 |
+
msgid "Apple Pay payment failed. %s"
|
793 |
msgstr ""
|
794 |
|
795 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:226
|
796 |
+
msgid "Not available for subscription products."
|
797 |
msgstr ""
|
798 |
|
799 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:231
|
800 |
+
msgid "Not available for pre-order products that are set to charge upon release."
|
|
|
|
|
|
|
|
|
|
|
801 |
msgstr ""
|
802 |
|
803 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:236
|
804 |
+
msgid "Buy Now is only available for simple products"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
805 |
msgstr ""
|
806 |
|
807 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:241
|
808 |
+
msgid "Product is not available for purchase."
|
|
|
809 |
msgstr ""
|
810 |
|
811 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:287
|
812 |
+
msgid "Cart contains subscriptions."
|
813 |
msgstr ""
|
814 |
|
815 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:291
|
816 |
+
msgid "Cart contains pre-orders."
|
|
|
817 |
msgstr ""
|
818 |
|
819 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:301
|
820 |
+
msgid "Apple Pay cannot be used for multiple shipments."
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
msgstr ""
|
822 |
|
823 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:336
|
824 |
+
msgid "Payment request data is missing."
|
|
|
|
|
|
|
825 |
msgstr ""
|
826 |
|
827 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:345
|
828 |
+
msgid "Cart data is missing."
|
829 |
msgstr ""
|
830 |
|
831 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:531
|
832 |
+
msgid "Subtotal"
|
833 |
msgstr ""
|
834 |
|
835 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:541
|
836 |
+
#: includes/Gateway/API/Requests/Orders.php:77
|
837 |
+
#: includes/Gateway/Digital_Wallet.php:426
|
838 |
+
msgid "Discount"
|
839 |
msgstr ""
|
840 |
|
841 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:551
|
842 |
+
#: includes/Gateway/Digital_Wallet.php:410
|
843 |
+
msgid "Shipping"
|
844 |
msgstr ""
|
845 |
|
846 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:561
|
847 |
+
#: includes/Gateway/Digital_Wallet.php:434
|
848 |
+
msgid "Fees"
|
|
|
|
|
|
|
849 |
msgstr ""
|
850 |
|
851 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php:571
|
852 |
+
msgid "Taxes"
|
|
|
|
|
|
|
|
|
853 |
msgstr ""
|
854 |
|
855 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:71
|
856 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:89
|
857 |
+
msgid "Apple Pay"
|
|
|
|
|
858 |
msgstr ""
|
859 |
|
860 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:95
|
861 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1071
|
862 |
+
#: includes/Gateway.php:586 includes/Gateway.php:756
|
863 |
+
msgid "Enable / Disable"
|
864 |
msgstr ""
|
865 |
|
866 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:96
|
867 |
+
msgid "Accept Apple Pay"
|
|
|
868 |
msgstr ""
|
869 |
|
870 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:103
|
871 |
+
msgid "Allow Apple Pay on"
|
|
|
872 |
msgstr ""
|
873 |
|
874 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:113
|
875 |
+
msgid "Button Style"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
876 |
msgstr ""
|
877 |
|
878 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:116
|
879 |
+
msgid "Black"
|
|
|
|
|
|
|
|
|
|
|
880 |
msgstr ""
|
881 |
|
882 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:117
|
883 |
+
msgid "White"
|
|
|
|
|
|
|
|
|
|
|
884 |
msgstr ""
|
885 |
|
886 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:118
|
887 |
+
msgid "White with outline"
|
|
|
|
|
|
|
|
|
888 |
msgstr ""
|
889 |
|
890 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:130
|
891 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1246
|
892 |
+
msgid "Connection Settings"
|
|
|
|
|
893 |
msgstr ""
|
894 |
|
895 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:136
|
896 |
+
msgid "Apple Merchant ID"
|
|
|
|
|
|
|
|
|
897 |
msgstr ""
|
898 |
|
899 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:140
|
900 |
+
msgid "This is found in your %1$sApple developer account%2$s"
|
901 |
msgstr ""
|
902 |
|
903 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:147
|
904 |
+
msgid "Certificate Path"
|
|
|
|
|
|
|
905 |
msgstr ""
|
906 |
|
907 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:149
|
908 |
msgid ""
|
909 |
+
"The full system path to your certificate file from Apple. For security "
|
910 |
+
"reasons you should store this outside of your web root."
|
911 |
msgstr ""
|
912 |
|
913 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:152
|
914 |
+
#. translators: Placeholders: %s - the server's web root path
|
915 |
+
msgid "For reference, your current web root path is: %s"
|
916 |
msgstr ""
|
917 |
|
918 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:165
|
919 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:175
|
920 |
+
msgid "Processing Gateway"
|
921 |
msgstr ""
|
922 |
|
923 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:183
|
924 |
+
msgid "Test Mode"
|
|
|
|
|
925 |
msgstr ""
|
926 |
|
927 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:184
|
928 |
+
msgid ""
|
929 |
+
"Enable to test Apple Pay functionality throughout your sites without "
|
930 |
+
"processing real payments."
|
931 |
msgstr ""
|
932 |
|
933 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:293
|
934 |
+
msgid "Your site must be served over HTTPS with a valid SSL certificate."
|
|
|
935 |
msgstr ""
|
936 |
|
937 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:303
|
938 |
+
#. translators: Placeholders: %1$s - plugin name, %2$s - a
|
939 |
+
#. currency/comma-separated list of currencies, %3$s - <a> tag, %4$s - </a> tag
|
940 |
+
msgid ""
|
941 |
+
"Accepts payment in %1$s only. %2$sConfigure%3$s WooCommerce to accept %1$s "
|
942 |
+
"to enable Apple Pay."
|
943 |
+
msgid_plural ""
|
944 |
+
"Accepts payment in one of %1$s only. %2$sConfigure%3$s WooCommerce to "
|
945 |
+
"accept one of %1$s to enable Apple Pay."
|
946 |
+
msgstr[0] ""
|
947 |
+
msgstr[1] ""
|
948 |
|
949 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:322
|
950 |
msgid ""
|
951 |
+
"Your %1$sMerchant Identity Certificate%2$s cannot be found. Please check "
|
952 |
+
"your path configuration."
|
953 |
msgstr ""
|
954 |
|
955 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:329
|
956 |
+
msgid "Apple Pay is disabled."
|
957 |
msgstr ""
|
958 |
|
959 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:368
|
960 |
+
msgid "Single products"
|
|
|
|
|
|
|
|
|
961 |
msgstr ""
|
962 |
|
963 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:369
|
964 |
+
msgid "Cart"
|
965 |
msgstr ""
|
966 |
|
967 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php:370
|
968 |
+
msgid "Checkout"
|
|
|
|
|
|
|
|
|
|
|
969 |
msgstr ""
|
970 |
|
971 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Ajax.php:117
|
972 |
+
msgid "Could not validate merchant. %s"
|
973 |
msgstr ""
|
974 |
|
975 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php:155
|
976 |
+
msgid "Buy with"
|
|
|
|
|
|
|
|
|
|
|
977 |
msgstr ""
|
978 |
|
979 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php:186
|
980 |
+
msgid "Product does not exist."
|
981 |
msgstr ""
|
982 |
|
983 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php:289
|
984 |
+
msgid "Pay with"
|
985 |
msgstr ""
|
986 |
|
987 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php:295
|
988 |
+
msgid "or"
|
989 |
msgstr ""
|
990 |
|
991 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:72
|
992 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:79
|
993 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:92
|
994 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:101
|
995 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:113
|
996 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:157
|
997 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:167
|
998 |
+
#: includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php:169
|
999 |
+
msgid "Error %d: Unable to create order. Please try again."
|
1000 |
msgstr ""
|
1001 |
|
1002 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:136
|
1003 |
+
msgid "Order cannot be captured"
|
1004 |
msgstr ""
|
1005 |
|
1006 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:141
|
1007 |
+
msgid "Transaction authorization has expired"
|
1008 |
msgstr ""
|
1009 |
|
1010 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:146
|
1011 |
+
msgid "Transaction has already been fully captured"
|
|
|
|
|
1012 |
msgstr ""
|
1013 |
|
1014 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:151
|
1015 |
+
msgid "Transaction cannot be captured"
|
|
|
|
|
|
|
1016 |
msgstr ""
|
1017 |
|
1018 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:167
|
1019 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1020 |
+
#. Authorize.net, Braintree, etc), %2$s - transaction amount. Definitions:
|
1021 |
+
#. Capture, as in capture funds from a credit card.
|
1022 |
+
msgid "%1$s Capture of %2$s Approved"
|
1023 |
msgstr ""
|
1024 |
|
1025 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:174
|
1026 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:311
|
1027 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1873
|
1028 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2087
|
1029 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2387
|
1030 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:584
|
1031 |
+
#. translators: Placeholders: %s - transaction ID
|
1032 |
+
msgid "(Transaction ID %s)"
|
1033 |
msgstr ""
|
1034 |
|
1035 |
+
#: includes/Framework/PaymentGateway/Handlers/Capture.php:205
|
1036 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1037 |
+
#. Authorize.net, Braintree, etc), %2$s - failure message. Definitions:
|
1038 |
+
#. "capture" as in capturing funds from a credit card.
|
1039 |
+
msgid "%1$s Capture Failed: %2$s"
|
1040 |
msgstr ""
|
1041 |
|
1042 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:226
|
1043 |
+
msgid "Pre-Order Tokenization attempt failed (%s)"
|
1044 |
msgstr ""
|
1045 |
|
1046 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:272
|
1047 |
+
msgid "%s - Pre-Order Release Payment for Order %s"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1048 |
msgstr ""
|
1049 |
|
1050 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:276
|
1051 |
+
msgid "Payment token missing/invalid."
|
|
|
1052 |
msgstr ""
|
1053 |
|
1054 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:299
|
1055 |
+
msgid "%s %s Pre-Order Release Payment Approved: %s ending in %s (expires %s)"
|
|
|
|
|
1056 |
msgstr ""
|
1057 |
|
1058 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:328
|
1059 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1610
|
1060 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:678
|
1061 |
+
#. translators: This is a message describing that the transaction in question
|
1062 |
+
#. only performed a credit card authorization and did not capture any funds.
|
1063 |
+
msgid "Authorization only transaction"
|
1064 |
msgstr ""
|
1065 |
|
1066 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php:347
|
1067 |
+
msgid "Pre-Order Release Payment Failed: %s"
|
1068 |
msgstr ""
|
1069 |
|
1070 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:193
|
1071 |
+
msgid "Subscription Renewal: payment token is missing/invalid."
|
1072 |
msgstr ""
|
1073 |
|
1074 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:219
|
1075 |
+
msgid "%1$s - Subscription Renewal Order %2$s"
|
1076 |
msgstr ""
|
1077 |
|
1078 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:348
|
1079 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - error
|
1080 |
+
#. message; e.g. Order Note: [Payment method] Payment Change failed [error]
|
1081 |
+
msgid "%1$s Payment Change Failed (%2$s)"
|
1082 |
msgstr ""
|
1083 |
|
1084 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:353
|
1085 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2523
|
1086 |
+
#: includes/Gateway/Blocks_Handler.php:137
|
1087 |
+
#: includes/Gateway/Digital_Wallet.php:208
|
1088 |
+
#: includes/Gateway/Payment_Form.php:238 includes/Gateway.php:251
|
1089 |
+
msgid "An error occurred, please try again or try an alternate form of payment."
|
1090 |
msgstr ""
|
1091 |
|
1092 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:488
|
1093 |
+
msgid "Via %s ending in %s"
|
|
|
1094 |
msgstr ""
|
1095 |
|
1096 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:515
|
1097 |
+
msgid "Subscriptions"
|
|
|
1098 |
msgstr ""
|
1099 |
|
1100 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:584
|
1101 |
+
msgid ""
|
1102 |
+
"This payment method is tied to a subscription and cannot be deleted. Please "
|
1103 |
+
"switch the subscription to another method first."
|
1104 |
msgstr ""
|
1105 |
|
1106 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:636
|
1107 |
+
msgid "Payment Token"
|
1108 |
msgstr ""
|
1109 |
|
1110 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:665
|
1111 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:670
|
1112 |
+
msgid "%s is required."
|
1113 |
msgstr ""
|
1114 |
|
1115 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:136
|
1116 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2177
|
1117 |
+
#. translators: Placeholders: %1$s - payment request response status code, %2$s
|
1118 |
+
#. - payment request response status message
|
1119 |
+
#. translators: Placeholders: %1$s - status code, %2$s - status message
|
1120 |
+
msgid "Status code %1$s: %2$s"
|
1121 |
msgstr ""
|
1122 |
|
1123 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:139
|
1124 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2180
|
1125 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:791
|
1126 |
+
#. translators: Placeholders: %s - payment request response status code
|
1127 |
+
#. translators: Placeholders: %s - status code
|
1128 |
+
msgid "Status code: %s"
|
1129 |
msgstr ""
|
1130 |
|
1131 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:142
|
1132 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2183
|
1133 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:793
|
1134 |
+
#. translators: Placeholders: %s - payment request response status message
|
1135 |
+
#. translators: Placeholders; %s - status message
|
1136 |
+
msgid "Status message: %s"
|
1137 |
msgstr ""
|
1138 |
|
1139 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:144
|
1140 |
+
msgid "Unknown Error"
|
1141 |
msgstr ""
|
1142 |
|
1143 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:149
|
1144 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2188
|
1145 |
+
msgid "Transaction ID %s"
|
1146 |
msgstr ""
|
1147 |
|
1148 |
+
#: includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php:803
|
1149 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1150 |
+
#. Authorize.net, Braintree, etc), %2$s - payment method name (mastercard, bank
|
1151 |
+
#. account, etc), %3$s - last four digits of the card/account, %4$s -
|
1152 |
+
#. card/account expiry date
|
1153 |
+
msgid "%1$s Payment Method Saved: %2$s ending in %3$s (expires %4$s)"
|
1154 |
msgstr ""
|
1155 |
|
1156 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:305
|
1157 |
+
msgid "you successfully processed a payment!"
|
1158 |
msgstr ""
|
1159 |
|
1160 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:310
|
1161 |
+
msgid "you successfully processed a refund!"
|
1162 |
msgstr ""
|
1163 |
|
1164 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:437
|
1165 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:164
|
1166 |
+
msgid "Card number is missing"
|
1167 |
msgstr ""
|
1168 |
|
1169 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:438
|
1170 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:180
|
1171 |
+
msgid "Card number is invalid"
|
1172 |
msgstr ""
|
1173 |
|
1174 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:439
|
1175 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:175
|
1176 |
+
msgid "Card number is invalid (only digits allowed)"
|
1177 |
msgstr ""
|
1178 |
|
1179 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:440
|
1180 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:170
|
1181 |
+
msgid "Card number is invalid (wrong length)"
|
1182 |
msgstr ""
|
1183 |
|
1184 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:441
|
1185 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:219
|
1186 |
+
msgid "Card security code is missing"
|
1187 |
msgstr ""
|
1188 |
|
1189 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:442
|
1190 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:207
|
1191 |
+
msgid "Card security code is invalid (only digits are allowed)"
|
|
|
|
|
|
|
|
|
1192 |
msgstr ""
|
1193 |
|
1194 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:443
|
1195 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:213
|
1196 |
+
msgid "Card security code is invalid (must be 3 or 4 digits)"
|
1197 |
msgstr ""
|
1198 |
|
1199 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:444
|
1200 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:140
|
1201 |
+
msgid "Card expiration date is invalid"
|
1202 |
msgstr ""
|
1203 |
|
1204 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:445
|
1205 |
+
msgid "Check Number is invalid (only digits are allowed)"
|
1206 |
msgstr ""
|
1207 |
|
1208 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:446
|
1209 |
+
msgid "Check Number is missing"
|
1210 |
msgstr ""
|
1211 |
|
1212 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:447
|
1213 |
+
msgid "Drivers license state is missing"
|
1214 |
msgstr ""
|
1215 |
|
1216 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:448
|
1217 |
+
msgid "Drivers license number is missing"
|
1218 |
msgstr ""
|
1219 |
|
1220 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:449
|
1221 |
+
msgid "Drivers license number is invalid"
|
1222 |
msgstr ""
|
1223 |
|
1224 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:450
|
1225 |
+
msgid "Account Number is missing"
|
1226 |
msgstr ""
|
1227 |
|
1228 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:451
|
1229 |
+
msgid "Account Number is invalid (only digits are allowed)"
|
1230 |
msgstr ""
|
1231 |
|
1232 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:452
|
1233 |
+
msgid "Account number is invalid (must be between 5 and 17 digits)"
|
1234 |
msgstr ""
|
1235 |
|
1236 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:453
|
1237 |
+
msgid "Routing Number is missing"
|
1238 |
msgstr ""
|
1239 |
|
1240 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:454
|
1241 |
+
msgid "Routing Number is invalid (only digits are allowed)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1242 |
msgstr ""
|
1243 |
|
1244 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:455
|
1245 |
+
msgid "Routing number is invalid (must be 9 digits)"
|
1246 |
msgstr ""
|
1247 |
|
1248 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:593
|
1249 |
+
msgid "Continue"
|
1250 |
msgstr ""
|
1251 |
|
1252 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:593
|
1253 |
+
msgid "Place order"
|
1254 |
msgstr ""
|
1255 |
|
1256 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:625
|
1257 |
+
msgid "Thank you for your order."
|
|
|
|
|
1258 |
msgstr ""
|
1259 |
|
1260 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1034
|
1261 |
+
#: includes/Gateway/Blocks_Handler.php:152
|
1262 |
+
msgid "Credit Card"
|
1263 |
msgstr ""
|
1264 |
|
1265 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1052
|
1266 |
+
msgid "Pay securely using your credit card."
|
1267 |
msgstr ""
|
1268 |
|
1269 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1072
|
1270 |
+
#: includes/Gateway.php:587
|
1271 |
+
msgid "Enable this gateway"
|
1272 |
msgstr ""
|
1273 |
|
1274 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1078
|
1275 |
+
#: includes/Gateway.php:593
|
1276 |
+
msgid "Title"
|
1277 |
msgstr ""
|
1278 |
|
1279 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1080
|
1280 |
+
#: includes/Gateway.php:595
|
1281 |
+
msgid "Payment method title that the customer will see during checkout."
|
1282 |
msgstr ""
|
1283 |
|
1284 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1085
|
1285 |
+
#: includes/Gateway.php:600
|
1286 |
+
msgid "Description"
|
1287 |
msgstr ""
|
1288 |
|
1289 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1087
|
1290 |
+
#: includes/Gateway.php:602
|
1291 |
+
msgid "Payment method description that the customer will see during checkout."
|
1292 |
msgstr ""
|
1293 |
|
1294 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1116
|
1295 |
+
#: includes/Gateway.php:636
|
1296 |
+
msgid "Detailed Decline Messages"
|
1297 |
msgstr ""
|
1298 |
|
1299 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1118
|
1300 |
+
#: includes/Gateway.php:638
|
1301 |
+
msgid ""
|
1302 |
+
"Check to enable detailed decline messages to the customer during checkout "
|
1303 |
+
"when possible, rather than a generic decline message."
|
1304 |
msgstr ""
|
1305 |
|
1306 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1128
|
1307 |
+
#: includes/Gateway.php:648
|
1308 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
1309 |
+
msgid ""
|
1310 |
+
"Show Detailed Error Messages and API requests/responses on the checkout "
|
1311 |
+
"page and/or save them to the %1$sdebug log%2$s"
|
1312 |
msgstr ""
|
1313 |
|
1314 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1132
|
1315 |
+
#: includes/Gateway.php:652
|
1316 |
+
msgid "Show on Checkout Page"
|
1317 |
msgstr ""
|
1318 |
|
1319 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1135
|
1320 |
+
#: includes/Gateway.php:655
|
1321 |
+
#. translators: show debugging information on both checkout page and in the log
|
1322 |
+
msgid "Both"
|
1323 |
msgstr ""
|
1324 |
|
1325 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1198
|
1326 |
+
msgid "Select the gateway environment to use for transactions."
|
1327 |
msgstr ""
|
1328 |
|
1329 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1252
|
1330 |
+
msgid "Share connection settings"
|
1331 |
msgstr ""
|
1332 |
|
1333 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1254
|
1334 |
+
msgid "Use connection/authentication settings from other gateway"
|
1335 |
msgstr ""
|
1336 |
|
1337 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1257
|
1338 |
+
msgid "Disabled because the other gateway is using these settings"
|
1339 |
msgstr ""
|
1340 |
|
1341 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1274
|
1342 |
+
msgid "Card Verification (CSC)"
|
1343 |
msgstr ""
|
1344 |
|
1345 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1275
|
1346 |
+
msgid "Display the Card Security Code (CV2) field on checkout"
|
|
|
|
|
1347 |
msgstr ""
|
1348 |
|
1349 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1283
|
1350 |
+
msgid "Saved Card Verification"
|
1351 |
msgstr ""
|
1352 |
|
1353 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1284
|
1354 |
+
msgid "Display the Card Security Code field when paying with a saved card"
|
1355 |
msgstr ""
|
1356 |
|
1357 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1566
|
1358 |
+
#. translators: Placeholders: %1$s - site title, %2$s - order number
|
1359 |
+
msgid "%1$s - Order %2$s"
|
1360 |
msgstr ""
|
1361 |
|
1362 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1691
|
1363 |
+
#. translators: Placeholders: %1$s - site title, %2$s - order number.
|
1364 |
+
#. Definitions: Capture as in capture funds from a credit card.
|
1365 |
+
msgid "%1$s - Capture for Order %2$s"
|
1366 |
msgstr ""
|
1367 |
|
1368 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1813
|
1369 |
+
#. translators: Placeholders: %1$s - site title, %2$s - order number
|
1370 |
+
msgid "%1$s - Refund for Order %2$s"
|
1371 |
msgstr ""
|
1372 |
|
1373 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1866
|
1374 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1375 |
+
#. Authorize.net, Braintree, etc), %2$s - a monetary amount
|
1376 |
+
msgid "%1$s Refund in the amount of %2$s approved."
|
1377 |
msgstr ""
|
1378 |
|
1379 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1894
|
1380 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1381 |
+
#. Authorize.net, Braintree, etc), %2$s - error code, %3$s - error message
|
1382 |
+
msgid "%1$s Refund Failed: %2$s - %3$s"
|
1383 |
msgstr ""
|
1384 |
|
1385 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1902
|
1386 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1387 |
+
#. Authorize.net, Braintree, etc), %2$s - error message
|
1388 |
+
msgid "%1$s Refund Failed: %2$s"
|
|
|
|
|
|
|
|
|
1389 |
msgstr ""
|
1390 |
|
1391 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1923
|
1392 |
+
#. translators: Placeholders: %s - payment gateway title (such as
|
1393 |
+
#. Authorize.net, Braintree, etc)
|
1394 |
+
msgid "%s Order completely refunded."
|
1395 |
msgstr ""
|
1396 |
|
1397 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:1978
|
1398 |
+
msgid ""
|
1399 |
+
"Oops, you cannot partially void this order. Please use the full order "
|
1400 |
+
"amount."
|
1401 |
msgstr ""
|
1402 |
|
1403 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2048
|
1404 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - error code,
|
1405 |
+
#. %3$s - error message. Void as in to void an order.
|
1406 |
+
msgid "%1$s Void Failed: %2$s - %3$s"
|
1407 |
msgstr ""
|
1408 |
|
1409 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2056
|
1410 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - error
|
1411 |
+
#. message. Void as in to void an order.
|
1412 |
+
msgid "%1$s Void Failed: %2$s"
|
|
|
|
|
|
|
|
|
1413 |
msgstr ""
|
1414 |
|
1415 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2080
|
1416 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - a monetary
|
1417 |
+
#. amount. Void as in to void an order.
|
1418 |
+
msgid "%1$s Void in the amount of %2$s approved."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1419 |
msgstr ""
|
1420 |
|
1421 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2358
|
1422 |
+
#. translators: Placeholders: %1$s - payment method title, %2$s - environment
|
1423 |
+
#. ("Test"), %3$s - transaction type (authorization/charge)
|
1424 |
+
msgid "%1$s %2$s %3$s Approved"
|
1425 |
+
msgstr ""
|
|
|
1426 |
|
1427 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2368
|
1428 |
+
#. translators: Placeholders: %1$s - credit card type (MasterCard, Visa,
|
1429 |
+
#. etc...), %2$s - last four digits of the card
|
1430 |
+
msgid "%1$s ending in %2$s"
|
1431 |
msgstr ""
|
1432 |
|
1433 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2379
|
1434 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:576
|
1435 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:528
|
1436 |
+
#. translators: Placeholders: %s - expiry date
|
1437 |
+
msgid "(expires %s)"
|
1438 |
msgstr ""
|
1439 |
|
1440 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2418
|
1441 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - message
|
1442 |
+
#. (probably reason for the transaction being held for review)
|
1443 |
+
msgid "%1$s Transaction Held for Review (%2$s)"
|
|
|
1444 |
msgstr ""
|
1445 |
|
1446 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2459
|
1447 |
+
msgid ""
|
1448 |
+
"Your order has been received and is being reviewed. Thank you for your "
|
1449 |
+
"business."
|
1450 |
msgstr ""
|
1451 |
|
1452 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2506
|
1453 |
+
#. translators: Placeholders: %1$s - payment gateway title, %2$s - error
|
1454 |
+
#. message; e.g. Order Note: [Payment method] Payment failed [error]
|
1455 |
+
msgid "%1$s Payment Failed (%2$s)"
|
1456 |
msgstr ""
|
1457 |
|
1458 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2755
|
1459 |
+
msgid "Transaction Type"
|
1460 |
msgstr ""
|
1461 |
|
1462 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2757
|
1463 |
+
msgid ""
|
1464 |
+
"Select how transactions should be processed. Charge submits all "
|
1465 |
+
"transactions for settlement, Authorization simply authorizes the order "
|
1466 |
+
"total for capture later."
|
1467 |
msgstr ""
|
1468 |
|
1469 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2768
|
1470 |
+
msgid "Charge Virtual-Only Orders"
|
1471 |
msgstr ""
|
1472 |
|
1473 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2770
|
1474 |
+
msgid ""
|
1475 |
+
"If the order contains exclusively virtual items, enable this to immediately "
|
1476 |
+
"charge, rather than authorize, the transaction."
|
1477 |
msgstr ""
|
1478 |
|
1479 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2778
|
1480 |
+
msgid "Enable Partial Capture"
|
1481 |
+
msgstr ""
|
|
|
|
|
1482 |
|
1483 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2780
|
1484 |
+
msgid "Allow orders to be partially captured multiple times."
|
1485 |
+
msgstr ""
|
|
|
|
|
1486 |
|
1487 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2792
|
1488 |
+
msgid "Capture Paid Orders"
|
1489 |
msgstr ""
|
1490 |
|
1491 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2795
|
1492 |
+
msgid "Automatically capture orders when they are changed to %s."
|
1493 |
msgstr ""
|
1494 |
|
1495 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2796
|
1496 |
+
msgid "a paid status"
|
1497 |
msgstr ""
|
1498 |
|
1499 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2986
|
1500 |
+
msgid "Accepted Card Logos"
|
1501 |
msgstr ""
|
1502 |
|
1503 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2988
|
1504 |
+
msgid ""
|
1505 |
+
"These are the card logos that are displayed to customers as accepted during "
|
1506 |
+
"checkout."
|
1507 |
msgstr ""
|
1508 |
|
1509 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2991
|
1510 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag
|
1511 |
+
msgid ""
|
1512 |
+
"This setting %1$sdoes not%2$s change which card types the gateway will "
|
1513 |
+
"accept. Accepted cards are configured from your payment processor account."
|
1514 |
msgstr ""
|
1515 |
|
1516 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3082
|
1517 |
+
#. translators:
|
1518 |
+
#. http:www.cybersource.com/products/payment_security/payment_tokenization/ and
|
1519 |
+
#. https:en.wikipedia.org/wiki/Tokenization_(data_security)
|
1520 |
+
msgid "Tokenization"
|
1521 |
msgstr ""
|
1522 |
|
1523 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3083
|
1524 |
+
msgid "Allow customers to securely save their payment details for future checkout."
|
|
|
1525 |
msgstr ""
|
1526 |
|
1527 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:42
|
1528 |
+
msgid ""
|
1529 |
+
"Payment error, please try another payment method or contact us to complete "
|
1530 |
+
"your transaction."
|
1531 |
msgstr ""
|
1532 |
|
1533 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:387
|
1534 |
+
msgid "Unknown error"
|
1535 |
msgstr ""
|
1536 |
|
1537 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:396
|
1538 |
+
msgid "Payment method address could not be updated. %s"
|
1539 |
msgstr ""
|
1540 |
|
1541 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:563
|
1542 |
+
#. translators: Placeholders: %1$s - payment method title, %2$s - environment
|
1543 |
+
#. ("Test"), %3$s - transaction type (authorization/charge), %4$s - card type
|
1544 |
+
#. (mastercard, visa, ...), %5$s - last four digits of the card
|
1545 |
+
msgid "%1$s %2$s %3$s Approved: %4$s ending in %5$s"
|
1546 |
msgstr ""
|
1547 |
|
1548 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:646
|
1549 |
+
#. translators: Placeholders: %s - failure message
|
1550 |
+
msgid "Tokenization Request Failed: %s"
|
1551 |
msgstr ""
|
1552 |
|
1553 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:657
|
1554 |
+
#. translators: Placeholders: %1$s - payment method title, %2$s - failure
|
1555 |
+
#. message
|
1556 |
+
msgid "%1$s Tokenization Request Failed: %2$s"
|
1557 |
msgstr ""
|
1558 |
|
1559 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:715
|
1560 |
+
#. translators: Placeholders: %s - failure message. Payment method as in a
|
1561 |
+
#. specific credit card, e-check or bank account
|
1562 |
+
msgid "Oops, adding your new payment method failed: %s"
|
1563 |
msgstr ""
|
1564 |
|
1565 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:756
|
1566 |
+
#. translators: Payment method as in a specific credit card. Placeholders: %1$s
|
1567 |
+
#. - card type (visa, mastercard, ...), %2$s - last four digits of the card,
|
1568 |
+
#. %3$s - card expiry date
|
1569 |
+
msgid "Nice! New payment method added: %1$s ending in %2$s (expires %3$s)"
|
1570 |
+
msgstr ""
|
1571 |
+
|
1572 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:764
|
1573 |
+
#. translators: Payment method as in a specific credit card, e-check or bank
|
1574 |
+
#. account
|
1575 |
+
msgid "Nice! New payment method added."
|
1576 |
msgstr ""
|
1577 |
|
1578 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:789
|
1579 |
+
msgid "Status code %s: %s"
|
1580 |
msgstr ""
|
1581 |
|
1582 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:884
|
1583 |
+
#. translators: Placeholders: %1$s - site title, %2$s - customer email. Payment
|
1584 |
+
#. method as in a specific credit card, e-check or bank account
|
1585 |
+
msgid "%1$s - Add Payment Method for %2$s"
|
1586 |
msgstr ""
|
1587 |
|
1588 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:152
|
1589 |
+
msgid "PayPal"
|
1590 |
msgstr ""
|
1591 |
|
1592 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:153
|
1593 |
+
msgid "Checking Account"
|
1594 |
msgstr ""
|
1595 |
|
1596 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:154
|
1597 |
+
msgid "Savings Account"
|
|
|
1598 |
msgstr ""
|
1599 |
|
1600 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:155
|
1601 |
+
msgid "Credit / Debit Card"
|
1602 |
+
msgstr ""
|
1603 |
+
|
1604 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:156
|
1605 |
+
msgid "Bank Account"
|
1606 |
+
msgstr ""
|
1607 |
+
|
1608 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:202
|
1609 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:631
|
1610 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:35
|
1611 |
+
msgid "Edit"
|
1612 |
msgstr ""
|
1613 |
|
1614 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:204
|
1615 |
+
msgid "Oops, there was an error updating your payment method. Please try again."
|
1616 |
msgstr ""
|
1617 |
|
1618 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:205
|
1619 |
+
msgid "Are you sure you want to delete this payment method?"
|
1620 |
msgstr ""
|
1621 |
|
1622 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:311
|
1623 |
+
msgid "Method"
|
1624 |
msgstr ""
|
1625 |
|
1626 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:312
|
1627 |
+
msgid "Details"
|
|
|
1628 |
msgstr ""
|
1629 |
|
1630 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:313
|
1631 |
+
msgid "Expires"
|
1632 |
msgstr ""
|
1633 |
|
1634 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:314
|
1635 |
+
msgid "Default?"
|
1636 |
msgstr ""
|
1637 |
|
1638 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:351
|
1639 |
+
msgid "Credit/Debit Cards"
|
1640 |
msgstr ""
|
1641 |
|
1642 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:360
|
1643 |
+
msgid "Bank Accounts"
|
1644 |
msgstr ""
|
1645 |
|
1646 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:415
|
1647 |
+
msgid "N/A"
|
1648 |
+
msgstr ""
|
1649 |
+
|
1650 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:511
|
1651 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:174
|
1652 |
+
msgid "Nickname"
|
1653 |
+
msgstr ""
|
1654 |
+
|
1655 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:692
|
1656 |
+
#: includes/Sync/Records/Record.php:544
|
1657 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:92
|
1658 |
+
msgid "Delete"
|
1659 |
+
msgstr ""
|
1660 |
+
|
1661 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:846
|
1662 |
+
msgid "Oops, you took too long, please try again."
|
1663 |
+
msgstr ""
|
1664 |
+
|
1665 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:859
|
1666 |
+
msgid "There was an error with your request, please try again."
|
1667 |
+
msgstr ""
|
1668 |
+
|
1669 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:872
|
1670 |
+
#. translators: Payment method as in a specific credit card, e-check or bank
|
1671 |
+
#. account
|
1672 |
+
msgid "Error removing payment method"
|
1673 |
+
msgstr ""
|
1674 |
+
|
1675 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php:877
|
1676 |
+
#. translators: Payment method as in a specific credit card, e-check or bank
|
1677 |
+
#. account
|
1678 |
+
msgid "Payment method deleted."
|
1679 |
+
msgstr ""
|
1680 |
+
|
1681 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:268
|
1682 |
+
msgid "Card Number"
|
1683 |
+
msgstr ""
|
1684 |
+
|
1685 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:289
|
1686 |
+
msgid "MM / YY"
|
1687 |
+
msgstr ""
|
1688 |
+
|
1689 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:307
|
1690 |
+
msgid "Card Security Code"
|
1691 |
+
msgstr ""
|
1692 |
+
|
1693 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:310
|
1694 |
+
msgid "CSC"
|
1695 |
+
msgstr ""
|
1696 |
+
|
1697 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:355
|
1698 |
+
#. translators: Test mode refers to the current software environment
|
1699 |
+
msgid "TEST MODE ENABLED"
|
1700 |
+
msgstr ""
|
1701 |
+
|
1702 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:430
|
1703 |
+
#. translators: Payment method as in a specific credit card, eCheck or bank
|
1704 |
+
#. account
|
1705 |
+
msgid "Manage Payment Methods"
|
1706 |
+
msgstr ""
|
1707 |
+
|
1708 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:567
|
1709 |
+
msgid "Use a new card"
|
1710 |
msgstr ""
|
1711 |
|
1712 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:567
|
1713 |
+
msgid "Use a new bank account"
|
1714 |
msgstr ""
|
1715 |
|
1716 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Payment_Form.php:630
|
1717 |
+
#. translators: account as in customer's account on the eCommerce site
|
1718 |
+
msgid "Securely Save to Account"
|
1719 |
msgstr ""
|
1720 |
|
1721 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:550
|
1722 |
+
#. translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a>
|
1723 |
+
#. tag
|
1724 |
+
msgid ""
|
1725 |
+
"%1$s: WooCommerce is not being forced over SSL; your customers' payment "
|
1726 |
+
"data may be at risk. %2$sVerify your site URLs here%3$s"
|
1727 |
msgstr ""
|
1728 |
|
1729 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:567
|
1730 |
+
#. translators: Placeholders: %s - payment gateway name
|
1731 |
msgid ""
|
1732 |
+
"%s will soon require TLS 1.2 support to process transactions and your "
|
1733 |
+
"server environment may need to be updated. Please contact your hosting "
|
1734 |
+
"provider to confirm that your site can send and receive TLS 1.2 connections "
|
1735 |
+
"and request they make any necessary updates."
|
1736 |
+
msgstr ""
|
|
|
|
|
1737 |
|
1738 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:623
|
1739 |
+
#. translators: Placeholders: %1$s - plugin name, %2$s - a
|
1740 |
+
#. currency/comma-separated list of currencies, %3$s - <a> tag, %4$s - </a> tag
|
1741 |
msgid ""
|
1742 |
+
"%1$s accepts payment in %2$s only. %3$sConfigure%4$s WooCommerce to accept "
|
1743 |
+
"%2$s to enable this gateway for checkout."
|
1744 |
msgid_plural ""
|
1745 |
+
"%1$s accepts payment in one of %2$s only. %3$sConfigure%4$s WooCommerce to "
|
1746 |
+
"accept one of %2$s to enable this gateway for checkout."
|
1747 |
msgstr[0] ""
|
1748 |
msgstr[1] ""
|
1749 |
|
1750 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:658
|
1751 |
+
#. translators: Placeholders: %1$s - payment gateway name, %2$s - opening <a>
|
1752 |
+
#. tag, %3$s - closing </a> tag
|
1753 |
+
msgid ""
|
1754 |
+
"Heads up! %1$s is currently configured to log transaction data for "
|
1755 |
+
"debugging purposes. If you are not experiencing any problems with payment "
|
1756 |
+
"processing, we recommend %2$sturning off Debug Mode%3$s"
|
1757 |
+
msgstr ""
|
1758 |
+
|
1759 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:697
|
1760 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1761 |
+
#. Authorize.net, Braintree, etc), %2$s - <a> tag, %3$s - </a> tag
|
1762 |
+
msgid ""
|
1763 |
+
"%1$s is inactive for subscription transactions. Please %2$senable "
|
1764 |
+
"tokenization%3$s to activate %1$s for Subscriptions."
|
1765 |
+
msgstr ""
|
1766 |
+
|
1767 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:715
|
1768 |
+
#. translators: Placeholders: %1$s - payment gateway title (such as
|
1769 |
+
#. Authorize.net, Braintree, etc), %2$s - <a> tag, %3$s - </a> tag
|
1770 |
msgid ""
|
1771 |
+
"%1$s is inactive for pre-order transactions. Please %2$senable "
|
1772 |
+
"tokenization%3$s to activate %1$s for Pre-Orders."
|
1773 |
msgstr ""
|
1774 |
|
1775 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:752
|
1776 |
msgid ""
|
1777 |
+
"You must enable tokenization for this gateway in order to support automatic "
|
1778 |
+
"renewal payments with the WooCommerce Subscriptions extension."
|
1779 |
msgstr ""
|
1780 |
|
1781 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Plugin.php:753
|
1782 |
+
msgid "Inactive"
|
|
|
|
|
1783 |
msgstr ""
|
1784 |
|
1785 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:89
|
1786 |
+
msgid "%s Customer ID"
|
1787 |
+
msgstr ""
|
1788 |
+
|
1789 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:158
|
1790 |
+
msgid "Type"
|
1791 |
+
msgstr ""
|
1792 |
+
|
1793 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:228
|
1794 |
+
msgid "Removed payment token \"%d\""
|
1795 |
+
msgstr ""
|
1796 |
+
|
1797 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:273
|
1798 |
+
msgid "Account Type"
|
1799 |
+
msgstr ""
|
1800 |
+
|
1801 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Privacy.php:275
|
1802 |
+
msgid "Expiry Date"
|
1803 |
+
msgstr ""
|
1804 |
+
|
1805 |
+
#: includes/Framework/Plugin.php:208
|
1806 |
+
#. translators: Placeholders: %s - plugin name
|
1807 |
+
msgid "You cannot clone instances of %s."
|
1808 |
+
msgstr ""
|
1809 |
+
|
1810 |
+
#: includes/Framework/Plugin.php:219
|
1811 |
+
#. translators: Placeholders: %s - plugin name
|
1812 |
+
msgid "You cannot unserialize instances of %s."
|
1813 |
+
msgstr ""
|
1814 |
+
|
1815 |
+
#: includes/Framework/Plugin.php:348
|
1816 |
+
#. translators: Docs as in Documentation
|
1817 |
+
msgid "Docs"
|
1818 |
+
msgstr ""
|
1819 |
+
|
1820 |
+
#: includes/Framework/Plugin.php:437
|
1821 |
+
msgid "%1$s - A minimum of %2$s is required."
|
1822 |
+
msgstr ""
|
1823 |
+
|
1824 |
+
#: includes/Framework/Plugin.php:446
|
1825 |
+
msgid "Set as %1$s - %2$s is required."
|
1826 |
+
msgstr ""
|
1827 |
+
|
1828 |
+
#: includes/Framework/Plugin.php:631
|
1829 |
+
msgid "Configure"
|
1830 |
+
msgstr ""
|
1831 |
+
|
1832 |
+
#. Author of the plugin/theme
|
1833 |
+
msgid "WooCommerce"
|
1834 |
msgstr ""
|
1835 |
|
1836 |
+
#: includes/Framework/Plugin_Dependencies.php:125
|
1837 |
#. translators: Placeholders: %1$s - plugin name, %2$s - a PHP
|
1838 |
#. extension/comma-separated list of PHP extensions
|
1839 |
msgid ""
|
1846 |
msgstr[0] ""
|
1847 |
msgstr[1] ""
|
1848 |
|
1849 |
+
#: includes/Framework/Plugin_Dependencies.php:153
|
1850 |
#. translators: Placeholders: %1$s - plugin name, %2$s - a PHP
|
1851 |
#. function/comma-separated list of PHP functions
|
1852 |
msgid ""
|
1858 |
msgstr[0] ""
|
1859 |
msgstr[1] ""
|
1860 |
|
1861 |
+
#: includes/Framework/Plugin_Dependencies.php:183
|
1862 |
#. translators: Placeholders: %s - plugin name
|
1863 |
msgid ""
|
1864 |
"%s may behave unexpectedly because the following PHP configuration settings "
|
1865 |
"are required:"
|
1866 |
msgstr ""
|
1867 |
|
1868 |
+
#: includes/Framework/Plugin_Dependencies.php:197
|
1869 |
+
#. translators: Placeholders: %s - a PHP setting value
|
1870 |
msgid "%s or higher"
|
1871 |
msgstr ""
|
1872 |
|
1873 |
+
#: includes/Framework/Plugin_Dependencies.php:207
|
1874 |
msgid ""
|
1875 |
"Please contact your hosting provider or server administrator to configure "
|
1876 |
"these settings."
|
1877 |
msgstr ""
|
1878 |
|
1879 |
+
#: includes/Framework/Plugin_Dependencies.php:229
|
1880 |
#. translators: Placeholders: %1$s - <strong>, %2$s - </strong>
|
1881 |
msgid ""
|
1882 |
"Hey there! We've noticed that your server is running %1$san outdated "
|
1891 |
"resources to help you upgrade%5$s and to explain PHP versions further."
|
1892 |
msgstr ""
|
1893 |
|
1894 |
+
#: includes/Framework/Plugin_Dependencies.php:253
|
1895 |
#. translators: Placeholders: %1$s - WooCommerce version number, %2$s -
|
1896 |
#. <strong>, %3$s - </strong>, %4$s - Plugin name, %5$s - <a> tag, %6$s - </a>
|
1897 |
#. tag
|
1902 |
"soon as possible."
|
1903 |
msgstr ""
|
1904 |
|
1905 |
+
#: includes/Framework/Utilities/WP_Background_Job_Handler.php:619
|
1906 |
+
msgid "Every %d Minutes"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1907 |
msgstr ""
|
1908 |
|
1909 |
+
#: includes/Gateway/API/Requests/Orders.php:279
|
1910 |
+
#: includes/Gateway/API/Requests/Orders.php:318
|
1911 |
+
msgid "Adjustment"
|
1912 |
msgstr ""
|
1913 |
|
1914 |
+
#: includes/Gateway/Blocks_Handler.php:298
|
1915 |
+
#. translators: %1$s - opening bold HTML tag, %2$s - closing bold HTML tag,
|
1916 |
+
#. %3$s - version number
|
1917 |
+
msgid ""
|
1918 |
+
"%1$sWarning!%2$s Some Square + Checkout Block features do not work with "
|
1919 |
+
"your version of WooCommerce Blocks (%3$s). Please update to the latest "
|
1920 |
+
"version of WooCommerce Blocks or WooCommerce to fix these issues."
|
1921 |
msgstr ""
|
1922 |
|
1923 |
+
#: includes/Gateway/Digital_Wallet.php:114
|
1924 |
+
#. Translators: %1$s: expected location of apple pay verification file, %2$s:
|
1925 |
+
#. opening href tag with link to Square documentation, %3$s: closing href tag
|
1926 |
msgid ""
|
1927 |
+
"Apple Pay is not available with Square. We cannot confirm the Apple Pay "
|
1928 |
+
"domain verification file is at the expected location: %1$s. For more "
|
1929 |
+
"information, please read our documentation on %2$sSetting up Apple Pay%3$s."
|
1930 |
msgstr ""
|
1931 |
|
1932 |
+
#: includes/Gateway/Digital_Wallet.php:130
|
1933 |
+
#. Translators: %1$s: opening bold tags, %2$s: closing strong/bold tags, %3$s:
|
1934 |
+
#. expected location of apple pay verification file, %4$s: opening href tag
|
1935 |
+
#. with link to Square documentation, %5$s: closing href tag
|
1936 |
+
msgid ""
|
1937 |
+
"Apple Pay is not available with Square - there was a problem with "
|
1938 |
+
"registering your store domain with Square/Apple Pay. %1$sView the Square "
|
1939 |
+
"logs%2$s to find out what caused the registration to fail."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1940 |
msgstr ""
|
1941 |
|
1942 |
+
#: includes/Gateway/Digital_Wallet.php:177
|
1943 |
+
msgid "OR"
|
|
|
|
|
|
|
1944 |
msgstr ""
|
1945 |
|
1946 |
+
#: includes/Gateway/Digital_Wallet.php:279
|
1947 |
+
#. translators: product ID
|
1948 |
+
msgid "Product with the ID (%d) cannot be found."
|
1949 |
msgstr ""
|
1950 |
|
1951 |
+
#: includes/Gateway/Digital_Wallet.php:295
|
1952 |
+
#. translators: 1: product name 2: quantity in stock
|
1953 |
msgid ""
|
1954 |
+
"You cannot add that amount of \"%1$s\"; to the cart because there is not "
|
1955 |
+
"enough stock (%2$s remaining)."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1956 |
msgstr ""
|
1957 |
|
1958 |
+
#: includes/Gateway/Digital_Wallet.php:300
|
1959 |
+
#. translators: 1: product name
|
1960 |
+
msgid "You cannot purchase \"%1$s\" because it is currently not available."
|
1961 |
msgstr ""
|
1962 |
|
1963 |
+
#: includes/Gateway/Digital_Wallet.php:322
|
1964 |
+
#: includes/Gateway/Digital_Wallet.php:418
|
1965 |
+
msgid "Tax"
|
1966 |
msgstr ""
|
1967 |
|
1968 |
+
#: includes/Gateway/Digital_Wallet.php:357
|
1969 |
+
msgid "This payment method cannot be used for multiple shipments."
|
1970 |
msgstr ""
|
1971 |
|
1972 |
+
#: includes/Gateway/Digital_Wallet.php:368
|
1973 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:378
|
1974 |
+
msgid "Pending"
|
1975 |
msgstr ""
|
1976 |
|
1977 |
+
#: includes/Gateway/Digital_Wallet.php:469
|
1978 |
+
#. translators: Context (product, cart, checkout or page)
|
1979 |
+
msgid "Empty payment request data for %s."
|
1980 |
msgstr ""
|
1981 |
|
1982 |
+
#: includes/Gateway/Digital_Wallet.php:663
|
1983 |
+
msgid "Empty cart"
|
1984 |
msgstr ""
|
1985 |
|
1986 |
+
#: includes/Gateway/Digital_Wallet.php:797
|
1987 |
+
msgid "Unable to verify domain with Apple Pay - missing access token."
|
|
|
|
|
|
|
1988 |
msgstr ""
|
1989 |
|
1990 |
+
#: includes/Gateway/Payment_Form.php:180
|
1991 |
+
msgid "Postal code"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1992 |
msgstr ""
|
1993 |
|
1994 |
+
#: includes/Gateway.php:83
|
1995 |
+
msgid "Allow customers to use Square to securely pay with their credit cards"
|
|
|
|
|
|
|
1996 |
msgstr ""
|
1997 |
|
1998 |
+
#: includes/Gateway.php:449
|
1999 |
+
msgid "Refunds must be made within %s of the original payment date."
|
2000 |
msgstr ""
|
2001 |
|
2002 |
+
#: includes/Gateway.php:473
|
2003 |
msgid ""
|
2004 |
+
"Could not find original transaction tender. Please refund this transaction "
|
2005 |
+
"from your Square dashboard."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2006 |
msgstr ""
|
2007 |
|
2008 |
+
#: includes/Gateway.php:629
|
2009 |
+
msgid "Advanced Settings"
|
2010 |
msgstr ""
|
2011 |
|
2012 |
+
#: includes/Gateway.php:691
|
2013 |
+
msgid "Customer Profiles"
|
2014 |
msgstr ""
|
2015 |
|
2016 |
+
#: includes/Gateway.php:692
|
2017 |
+
msgid ""
|
2018 |
+
"Check to enable tokenization and allow customers to securely save their "
|
2019 |
+
"payment details for future checkout."
|
2020 |
msgstr ""
|
2021 |
|
2022 |
+
#: includes/Gateway.php:750
|
2023 |
+
msgid "Digital Wallet Settings"
|
2024 |
msgstr ""
|
2025 |
|
2026 |
+
#: includes/Gateway.php:751
|
2027 |
+
msgid "Take payments on your store with Apple Pay and Google Pay."
|
|
|
2028 |
msgstr ""
|
2029 |
|
2030 |
+
#: includes/Gateway.php:758
|
2031 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
2032 |
+
msgid ""
|
2033 |
+
"Allow customers to pay with Apple Pay or Google Pay from your Product, Cart "
|
2034 |
+
"and Checkout pages. Read more about the availablity of digital wallets in "
|
2035 |
+
"our %1$sdocumentation%2$s."
|
2036 |
msgstr ""
|
2037 |
|
2038 |
+
#: includes/Gateway.php:761
|
2039 |
+
msgid "Enable digital wallets"
|
|
|
2040 |
msgstr ""
|
2041 |
|
2042 |
+
#: includes/Gateway.php:765
|
2043 |
+
msgid "Button Type"
|
|
|
2044 |
msgstr ""
|
2045 |
|
2046 |
+
#: includes/Gateway.php:766
|
2047 |
+
msgid ""
|
2048 |
+
"This setting only applies to the Apple Pay button. When Google Pay is "
|
2049 |
+
"available, the Google Pay button will always have the \"Buy with\" button "
|
2050 |
+
"text."
|
2051 |
msgstr ""
|
2052 |
|
2053 |
+
#: includes/Gateway.php:767
|
2054 |
+
msgid "Select which text is displayed on the digital wallet buttons."
|
|
|
2055 |
msgstr ""
|
2056 |
|
2057 |
+
#: includes/Gateway.php:779
|
2058 |
+
msgid "Apple Pay Button Color"
|
|
|
|
|
|
|
2059 |
msgstr ""
|
2060 |
|
2061 |
+
#: includes/Gateway.php:780
|
2062 |
+
msgid "Select the color of the Apple Pay button."
|
2063 |
msgstr ""
|
2064 |
|
2065 |
+
#: includes/Gateway.php:792
|
2066 |
+
msgid "Google Pay Button Color"
|
2067 |
msgstr ""
|
2068 |
|
2069 |
+
#: includes/Gateway.php:793
|
2070 |
+
msgid "Select the color of the Google Pay button."
|
2071 |
msgstr ""
|
2072 |
|
2073 |
+
#: includes/Gateway.php:804
|
2074 |
+
msgid "Hide Digital Wallet Buttons"
|
2075 |
msgstr ""
|
2076 |
|
2077 |
+
#: includes/Gateway.php:805
|
2078 |
+
msgid ""
|
2079 |
+
"Select any digital wallet buttons you don't want to be displayed on your "
|
2080 |
+
"store."
|
2081 |
msgstr ""
|
2082 |
|
2083 |
+
#: includes/Gateway.php:1089
|
2084 |
+
msgid " An error occurred, please try again or try an alternate form of payment."
|
2085 |
msgstr ""
|
2086 |
|
2087 |
+
#: includes/Handlers/Background_Job.php:236
|
2088 |
+
msgid "Clear Square Sync"
|
|
|
2089 |
msgstr ""
|
2090 |
|
2091 |
+
#: includes/Handlers/Background_Job.php:237
|
2092 |
+
msgid "Clear"
|
|
|
2093 |
msgstr ""
|
2094 |
|
2095 |
+
#: includes/Handlers/Background_Job.php:238
|
2096 |
+
msgid "This tool will clear any ongoing Square product syncs."
|
2097 |
msgstr ""
|
2098 |
|
2099 |
+
#: includes/Handlers/Background_Job.php:288
|
2100 |
+
msgid "Success! You can now sync your products."
|
|
|
|
|
2101 |
msgstr ""
|
2102 |
|
2103 |
+
#: includes/Handlers/Connection.php:101 includes/Handlers/Connection.php:169
|
2104 |
+
msgid "Sorry, you do not have permission to manage the Square connection."
|
2105 |
msgstr ""
|
2106 |
|
2107 |
+
#: includes/Handlers/Connection.php:113
|
2108 |
+
msgid "Square Error: We could not connect to Square. No access token was given.!"
|
2109 |
msgstr ""
|
2110 |
|
2111 |
+
#: includes/Handlers/Connection.php:177
|
2112 |
+
msgid "Disconnected successfully"
|
2113 |
msgstr ""
|
2114 |
|
2115 |
+
#: includes/Handlers/Connection.php:384
|
2116 |
+
msgid "Connect with Square"
|
2117 |
msgstr ""
|
2118 |
|
2119 |
+
#: includes/Handlers/Connection.php:404
|
2120 |
+
msgid "Disconnect from Square"
|
2121 |
msgstr ""
|
2122 |
|
2123 |
+
#: includes/Handlers/Product.php:175
|
2124 |
+
#. translators: Placeholder: %s category ID
|
2125 |
+
msgid ""
|
2126 |
+
"Square category with id (%s) was not imported to your Store. Please run "
|
2127 |
+
"Import Products from Square settings."
|
2128 |
msgstr ""
|
2129 |
|
2130 |
+
#: includes/Handlers/Product.php:309
|
2131 |
+
msgid "Product not synced with Square"
|
2132 |
msgstr ""
|
2133 |
|
2134 |
+
#: includes/Handlers/Products.php:66
|
2135 |
+
#. translators: Placeholder: %s - product name
|
2136 |
+
msgid ""
|
2137 |
+
"Please add an SKU to sync %s with Square. The SKU must match the item's SKU "
|
2138 |
+
"in your Square account."
|
2139 |
msgstr ""
|
2140 |
|
2141 |
+
#: includes/Handlers/Products.php:68
|
2142 |
+
#. translators: Placeholder: %s - product name
|
2143 |
+
msgid ""
|
2144 |
+
"Please add an SKU to every variation of %s for syncing with Square. Each "
|
2145 |
+
"SKU must be unique and match the corresponding item's SKU in your Square "
|
2146 |
+
"account."
|
2147 |
msgstr ""
|
2148 |
|
2149 |
+
#: includes/Handlers/Products.php:70
|
2150 |
+
#. translators: Placeholder: %s - product name
|
2151 |
+
msgid "%s has multiple variation attributes and cannot be synced with Square."
|
2152 |
msgstr ""
|
2153 |
|
2154 |
+
#: includes/Handlers/Products.php:250
|
2155 |
+
msgid "Update product data with Square data"
|
2156 |
msgstr ""
|
2157 |
|
2158 |
+
#: includes/Handlers/Products.php:250
|
2159 |
+
msgid "Send product data to Square"
|
2160 |
msgstr ""
|
2161 |
|
2162 |
+
#: includes/Handlers/Products.php:255
|
2163 |
+
msgid "Sync with Square"
|
2164 |
msgstr ""
|
2165 |
|
2166 |
+
#: includes/Handlers/Products.php:291
|
2167 |
+
msgid "Sync with Square?"
|
2168 |
msgstr ""
|
2169 |
|
2170 |
+
#: includes/Handlers/Products.php:295
|
2171 |
+
msgid "No change"
|
2172 |
msgstr ""
|
2173 |
|
2174 |
+
#: includes/Handlers/Products.php:297
|
2175 |
+
msgid "No"
|
|
|
2176 |
msgstr ""
|
2177 |
|
2178 |
+
#: includes/Handlers/Products.php:298
|
2179 |
+
msgid "Yes"
|
|
|
|
|
|
|
2180 |
msgstr ""
|
2181 |
|
2182 |
+
#: includes/Handlers/Products.php:304
|
2183 |
+
msgid "This product"
|
|
|
|
|
2184 |
msgstr ""
|
2185 |
|
2186 |
+
#: includes/Handlers/Products.php:675
|
2187 |
+
#. translators: Placeholder: %1$s - date (localized), %2$s - time (localized),
|
2188 |
+
#. %3$s - opening <a> HTML link tag, %4$s closing </a> HTML link tag
|
2189 |
msgid ""
|
2190 |
+
"The product catalog visibility has been set to \"hidden\", as a matching "
|
2191 |
+
"product could not be found in Square on %1$s at %2$s. %3$sCheck sync "
|
2192 |
+
"records%4$s."
|
2193 |
msgstr ""
|
2194 |
|
2195 |
+
#: includes/Handlers/Sync.php:291
|
2196 |
+
#. translators: Placeholder: %d number of products processed
|
2197 |
+
msgid "Updated data for %d product."
|
2198 |
+
msgid_plural "Updated data for %d products."
|
2199 |
+
msgstr[0] ""
|
2200 |
+
msgstr[1] ""
|
2201 |
|
2202 |
+
#: includes/Lifecycle.php:185
|
2203 |
+
msgid "Great"
|
2204 |
msgstr ""
|
2205 |
|
2206 |
+
#: includes/Plugin.php:288
|
2207 |
msgid ""
|
2208 |
+
"Heads up! There may be a problem with your connection to Square. In order "
|
2209 |
+
"to continue accepting payments, please %1$sdisconnect and re-connect your "
|
2210 |
+
"site%2$s."
|
2211 |
msgstr ""
|
2212 |
|
2213 |
+
#: includes/Plugin.php:305
|
2214 |
+
msgid "You are connected to Square!"
|
|
|
|
|
|
|
2215 |
msgstr ""
|
2216 |
|
2217 |
+
#: includes/Plugin.php:312
|
2218 |
+
msgid "To get started, set your business location."
|
2219 |
msgstr ""
|
2220 |
|
2221 |
+
#: includes/Plugin.php:318
|
2222 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
2223 |
+
msgid "Visit the %1$splugin settings%2$s to set your business location."
|
2224 |
msgstr ""
|
2225 |
|
2226 |
+
#: includes/Plugin.php:328
|
2227 |
+
msgid "You are ready to sync products!"
|
2228 |
msgstr ""
|
2229 |
|
2230 |
+
#: includes/Plugin.php:334
|
2231 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - product count, %3$s -
|
2232 |
+
#. </strong> tag, %4$s - <a> tag, %5$s - </a> tag
|
2233 |
+
msgid ""
|
2234 |
+
"%1$s%2$d products%3$s are marked \"sync with Square\". %4$sStart a new sync "
|
2235 |
+
"now »%5$s"
|
2236 |
msgstr ""
|
2237 |
|
2238 |
+
#: includes/Plugin.php:346
|
2239 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
2240 |
+
#. <a> tag, %4$s - </a> tag
|
2241 |
+
msgid ""
|
2242 |
+
"%1$sNo products%2$s are marked \"sync with Square\". %3$sUpdate your "
|
2243 |
+
"products to sync data »%4$s"
|
2244 |
msgstr ""
|
2245 |
|
2246 |
+
#: includes/Plugin.php:361
|
2247 |
+
msgid ""
|
2248 |
+
"Heads up! Square is configured to sync product inventory, but WooCommerce "
|
2249 |
+
"stock management is disabled. Please %1$senable stock management%2$s to "
|
2250 |
+
"ensure product inventory counts are kept in sync."
|
2251 |
msgstr ""
|
2252 |
|
2253 |
+
#: includes/Plugin.php:378
|
2254 |
+
msgid "To get started, connect with Square."
|
2255 |
msgstr ""
|
2256 |
|
2257 |
+
#: includes/Plugin.php:384
|
2258 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
2259 |
+
msgid "To get started, %1$sconnect with Square »%2$s"
|
2260 |
msgstr ""
|
2261 |
|
2262 |
+
#: includes/Plugin.php:392
|
2263 |
+
#. translators: Placeholders: %1$s - plugin name
|
2264 |
+
msgid "Thanks for installing %1$s!"
|
2265 |
msgstr ""
|
2266 |
|
2267 |
+
#: includes/Plugin.php:413
|
2268 |
+
#. translators: Placeholders: %1$s - plugin name, %2$ - plugin version number,
|
2269 |
+
#. %3$s - opening <a> HTML link tag, %4$s - closing </a> HTML link tag, %5$s -
|
2270 |
+
#. opening <a> HTML link tag, %6$s - closing </a> HTML link tag
|
2271 |
msgid ""
|
2272 |
+
"%1$s has been updated to version %2$s. In order to continue syncing product "
|
2273 |
+
"inventory, please make sure to disconnect and reconnect with Square from "
|
2274 |
+
"the %3$splugin settings%4$s and re-sync your products. Read more in the "
|
2275 |
+
"%5$supdated documentation%6$s."
|
2276 |
msgstr ""
|
2277 |
|
2278 |
+
#: includes/Plugin.php:453
|
2279 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
2280 |
+
#. 2-character country code, %4$s - comma separated list of 2-character country
|
2281 |
+
#. codes
|
2282 |
msgid ""
|
2283 |
+
"%1$sWooCommerce Square:%2$s Your base country is %3$s, but Square can’t "
|
2284 |
+
"accept transactions from merchants outside of %4$s."
|
2285 |
msgstr ""
|
2286 |
|
2287 |
+
#: includes/Plugin.php:496
|
2288 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
2289 |
+
#. <a> tag, %4$s - </a> tag
|
2290 |
msgid ""
|
2291 |
+
"%1$sWooCommerce Square:%2$s Automatic refreshing of the connection to "
|
2292 |
+
"Square is inactive. Please disconnect and reconnect to resolve."
|
2293 |
msgstr ""
|
2294 |
|
2295 |
+
#: includes/Plugin.php:528
|
2296 |
msgid ""
|
2297 |
+
"%1$sWooCommerce Square:%2$s Product prices are entered inclusive of tax, "
|
2298 |
+
"but Square does not support syncing tax-inclusive prices. Please make sure "
|
2299 |
+
"your Square tax rates match your WooCommerce tax rates."
|
2300 |
msgstr ""
|
2301 |
|
2302 |
+
#: includes/Plugin.php:559
|
2303 |
msgid ""
|
2304 |
+
"Heads up! Your store currency is %1$s but your configured Square business "
|
2305 |
+
"location currency is %2$s, so payments cannot be processed. Please "
|
2306 |
+
"%3$schoose a different business location%4$s or change your %5$sshop "
|
2307 |
+
"currency%6$s."
|
2308 |
msgstr ""
|
2309 |
|
2310 |
+
#. Plugin Name of the plugin/theme
|
2311 |
+
msgid "WooCommerce Square"
|
2312 |
msgstr ""
|
2313 |
|
2314 |
+
#: includes/Settings.php:140
|
2315 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
2316 |
msgid ""
|
2317 |
+
"Sync your products and inventory and also accept credit and debit card "
|
2318 |
+
"payments at checkout. %1$sClick here%2$s to configure payments."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2319 |
msgstr ""
|
2320 |
|
2321 |
+
#: includes/Settings.php:147
|
2322 |
+
msgid ""
|
2323 |
+
"Connect with Square to start syncing your products and inventory and also "
|
2324 |
+
"accept credit and debit card payments at checkout."
|
2325 |
msgstr ""
|
2326 |
|
2327 |
+
#: includes/Settings.php:158
|
2328 |
+
msgid "Enable Sandbox Mode"
|
2329 |
msgstr ""
|
2330 |
|
2331 |
+
#: includes/Settings.php:159
|
2332 |
+
msgid "Enable to set the plugin in sandbox mode."
|
2333 |
msgstr ""
|
2334 |
|
2335 |
+
#: includes/Settings.php:161
|
2336 |
+
msgid ""
|
2337 |
+
"After enabling you’ll see a new Sandbox settings section with two fields; "
|
2338 |
+
"Sandbox Application ID & Sandbox Access Token."
|
2339 |
msgstr ""
|
2340 |
|
2341 |
+
#: includes/Settings.php:166
|
2342 |
+
msgid "Sandbox settings"
|
|
|
2343 |
msgstr ""
|
2344 |
|
2345 |
+
#: includes/Settings.php:170
|
2346 |
+
#. translators: Placeholders: %1$s - URL.
|
2347 |
+
msgid "Sandbox details can be created at: %s"
|
2348 |
msgstr ""
|
2349 |
|
2350 |
+
#: includes/Settings.php:177
|
2351 |
+
msgid "Sandbox Application ID"
|
2352 |
msgstr ""
|
2353 |
|
2354 |
+
#: includes/Settings.php:179
|
2355 |
msgid ""
|
2356 |
+
"Application ID for the Sandbox Application, see the details in the My "
|
2357 |
+
"Applications section."
|
2358 |
msgstr ""
|
2359 |
|
2360 |
+
#: includes/Settings.php:184
|
2361 |
+
msgid "Sandbox Access Token"
|
2362 |
msgstr ""
|
2363 |
|
2364 |
+
#: includes/Settings.php:186
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2365 |
msgid ""
|
2366 |
+
"Access Token for the Sandbox Test Account, see the details in the Sandbox "
|
2367 |
+
"Test Account section. Make sure you use the correct Sandbox Access Token "
|
2368 |
+
"for your application. For a given Sandbox Test Account, each Authorized "
|
2369 |
+
"Application is assigned a different Access Token."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2370 |
msgstr ""
|
2371 |
|
2372 |
+
#: includes/Settings.php:193
|
2373 |
+
msgid "Business location"
|
2374 |
msgstr ""
|
2375 |
|
2376 |
+
#: includes/Settings.php:198
|
2377 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
2378 |
+
#. <a> tag, %4$s - </a> tag
|
2379 |
+
msgid ""
|
2380 |
+
"Select a location to link to this site. Only %1$sactive%2$s "
|
2381 |
+
"%3$slocations%4$s that support credit card processing in Square can be "
|
2382 |
+
"linked."
|
2383 |
msgstr ""
|
2384 |
|
2385 |
+
#: includes/Settings.php:208
|
2386 |
+
msgid "Product system of record"
|
2387 |
msgstr ""
|
2388 |
|
2389 |
+
#: includes/Settings.php:213
|
2390 |
+
#. translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag, %3$s -
|
2391 |
+
#. <a> tag, %4$s - </a> tag
|
2392 |
+
msgid ""
|
2393 |
+
"Choose where you will update data for synced products. Inventory in Square "
|
2394 |
+
"is %1$salways%2$s checked for adjustments when sync is enabled. %3$sClick "
|
2395 |
+
"here%4$s to read more about choosing a system of record."
|
2396 |
msgstr ""
|
2397 |
|
2398 |
+
#: includes/Settings.php:220
|
2399 |
+
msgid "Do not sync product data"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2400 |
msgstr ""
|
2401 |
|
2402 |
+
#: includes/Settings.php:228
|
2403 |
+
msgid "Sync inventory"
|
2404 |
msgstr ""
|
2405 |
|
2406 |
+
#: includes/Settings.php:229
|
2407 |
+
msgid "Enable to sync product inventory with Square"
|
2408 |
msgstr ""
|
2409 |
|
2410 |
+
#: includes/Settings.php:235
|
2411 |
+
msgid "Handle missing products"
|
2412 |
msgstr ""
|
2413 |
|
2414 |
+
#: includes/Settings.php:236
|
2415 |
+
msgid "Hide synced products when not found in Square"
|
2416 |
msgstr ""
|
2417 |
|
2418 |
+
#: includes/Settings.php:238
|
2419 |
msgid ""
|
2420 |
+
"Products not found in Square will be hidden in the WooCommerce product "
|
2421 |
+
"catalog."
|
|
|
|
|
|
|
|
|
|
|
2422 |
msgstr ""
|
2423 |
|
2424 |
+
#: includes/Settings.php:244
|
2425 |
+
msgid ""
|
2426 |
+
"Run an import to create new products in this WooCommerce store for each new "
|
2427 |
+
"product created in Square that has a unique SKU not existing in here. Needs "
|
2428 |
+
"to be run each time new items are created in Square."
|
2429 |
msgstr ""
|
2430 |
|
2431 |
+
#: includes/Settings.php:254
|
2432 |
+
msgid "Connection"
|
|
|
2433 |
msgstr ""
|
2434 |
|
2435 |
+
#: includes/Settings.php:271
|
2436 |
+
#. translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag
|
2437 |
+
msgid "Log debug messages to the %1$sWooCommerce status log%2$s"
|
2438 |
msgstr ""
|
2439 |
|
2440 |
+
#: includes/Settings.php:319
|
2441 |
+
msgid "Please choose a location"
|
|
|
2442 |
msgstr ""
|
2443 |
|
2444 |
+
#: includes/Settings.php:353
|
2445 |
+
msgid "Import all products from Square"
|
|
|
2446 |
msgstr ""
|
2447 |
|
2448 |
+
#: includes/Sync/Interval_Polling.php:98
|
2449 |
+
msgid "Updated data for %d category."
|
2450 |
+
msgid_plural "Updated data for %d categories."
|
2451 |
+
msgstr[0] ""
|
2452 |
+
msgstr[1] ""
|
2453 |
|
2454 |
+
#: includes/Sync/Interval_Polling.php:108
|
2455 |
+
msgid ""
|
2456 |
+
"Product category data could not be updated from Square. Invalid API "
|
2457 |
+
"response."
|
2458 |
msgstr ""
|
2459 |
|
2460 |
+
#: includes/Sync/Manual_Synchronization.php:925
|
2461 |
+
#. translators: Placeholder: %s - product ID
|
2462 |
+
msgid "Product %s could not be updated in Square."
|
2463 |
msgstr ""
|
2464 |
|
2465 |
+
#: includes/Sync/Product_Import.php:546
|
2466 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Square item
|
2467 |
+
#. variation name, %3$s - failure reason
|
2468 |
+
msgid "Could not import \"%1$s - %2$s\" from Square. %3$s"
|
2469 |
msgstr ""
|
2470 |
|
2471 |
+
#: includes/Sync/Product_Import.php:591
|
2472 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - failure reason
|
2473 |
+
msgid "Could not import \"%1$s\" from Square. %2$s"
|
2474 |
msgstr ""
|
2475 |
|
2476 |
+
#: includes/Sync/Product_Import.php:620
|
2477 |
+
msgid "Items with variable pricing cannot be imported."
|
|
|
2478 |
msgstr ""
|
2479 |
|
2480 |
+
#: includes/Sync/Product_Import.php:624
|
2481 |
+
msgid "Variations with missing SKUs cannot be imported."
|
|
|
2482 |
msgstr ""
|
2483 |
|
2484 |
+
#: includes/Sync/Product_Import.php:717 includes/Sync/Product_Import.php:994
|
2485 |
+
msgid "The SKU already exists on another product"
|
|
|
2486 |
msgstr ""
|
2487 |
|
2488 |
+
#: includes/Sync/Product_Import.php:909
|
2489 |
+
#. translators: Placeholders: %1$s - variation ID, %2$s - product name
|
2490 |
+
msgid "Variation #%1$s of %2$s"
|
2491 |
msgstr ""
|
2492 |
|
2493 |
+
#: includes/Sync/Product_Import.php:1288
|
2494 |
+
#. translators: Placeholders: %s - missing parameter name
|
2495 |
+
msgid "Missing parameter %s"
|
2496 |
msgstr ""
|
2497 |
|
2498 |
+
#: includes/Sync/Product_Import.php:1294
|
2499 |
+
#. translators: Placeholders: %s - comma separated list of valid product types
|
2500 |
+
msgid "Invalid product type - the product type must be any of these: %s"
|
2501 |
msgstr ""
|
2502 |
|
2503 |
+
#: includes/Sync/Product_Import.php:1345
|
2504 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Failure reason
|
2505 |
+
msgid "Could not update %1$s from Square. %2$s"
|
2506 |
msgstr ""
|
2507 |
|
2508 |
+
#: includes/Sync/Product_Import.php:1348
|
2509 |
+
#. translators: Placeholders: %1$s - Square item name, %2$s - Failure reason
|
2510 |
+
msgid "Could not import %1$s from Square. %2$s"
|
|
|
|
|
|
|
2511 |
msgstr ""
|
2512 |
|
2513 |
+
#: includes/Sync/Records/Record.php:205
|
2514 |
+
msgid "Info"
|
|
|
|
|
2515 |
msgstr ""
|
2516 |
|
2517 |
+
#: includes/Sync/Records/Record.php:206
|
2518 |
+
msgid "Notice"
|
|
|
|
|
|
|
2519 |
msgstr ""
|
2520 |
|
2521 |
+
#: includes/Sync/Records/Record.php:207
|
2522 |
+
msgid "Alert"
|
|
|
|
|
|
|
2523 |
msgstr ""
|
2524 |
|
2525 |
+
#: includes/Sync/Records/Record.php:373
|
2526 |
+
#. translators: Placeholder: %s - product name
|
2527 |
+
msgid "%s not found in Square."
|
2528 |
msgstr ""
|
2529 |
|
2530 |
+
#: includes/Sync/Records/Record.php:552
|
2531 |
+
msgid "Ignore"
|
|
|
|
|
2532 |
msgstr ""
|
2533 |
|
2534 |
+
#: includes/Sync/Records/Record.php:561
|
2535 |
+
msgid "Unlink"
|
|
|
|
|
2536 |
msgstr ""
|
2537 |
|
2538 |
+
#: includes/Utilities/Encryption_Utility.php:55
|
2539 |
+
msgid "Encryption is not supported on this site."
|
|
|
|
|
|
|
2540 |
msgstr ""
|
2541 |
|
2542 |
+
#: includes/Utilities/Encryption_Utility.php:72
|
2543 |
+
msgid "%1$s encryption is not available on this site. %2$s will be used instead."
|
|
|
|
|
|
|
2544 |
msgstr ""
|
2545 |
|
2546 |
+
#: includes/Utilities/Encryption_Utility.php:97
|
2547 |
+
msgid "No encryption method available"
|
|
|
|
|
2548 |
msgstr ""
|
2549 |
|
2550 |
+
#: includes/Utilities/Encryption_Utility.php:101
|
2551 |
+
msgid "Data must be a non-empty string or array"
|
|
|
|
|
2552 |
msgstr ""
|
2553 |
|
2554 |
+
#: includes/Utilities/Encryption_Utility.php:105
|
2555 |
+
#: includes/Utilities/Encryption_Utility.php:148
|
2556 |
+
msgid "Encryption key must be a string"
|
2557 |
msgstr ""
|
2558 |
|
2559 |
+
#: includes/Utilities/Encryption_Utility.php:117
|
2560 |
+
msgid "Could not generate encryption vector."
|
2561 |
msgstr ""
|
2562 |
|
2563 |
+
#: includes/Utilities/Encryption_Utility.php:140
|
2564 |
+
msgid "No decryption method available"
|
2565 |
msgstr ""
|
2566 |
|
2567 |
+
#: includes/Utilities/Encryption_Utility.php:144
|
2568 |
+
msgid "Data must be a non-empty string"
|
2569 |
msgstr ""
|
2570 |
|
2571 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ActionFactory.php:161
|
2572 |
+
msgid "Invalid action - must be a recurring action."
|
2573 |
msgstr ""
|
2574 |
|
2575 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:60
|
2576 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:75
|
2577 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:76
|
2578 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:89
|
2579 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:19
|
2580 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:30
|
2581 |
+
msgid "Scheduled Actions"
|
2582 |
msgstr ""
|
2583 |
|
2584 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:127
|
2585 |
+
msgid "About"
|
2586 |
msgstr ""
|
2587 |
|
2588 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:129
|
2589 |
+
msgid "About Action Scheduler %s"
|
2590 |
msgstr ""
|
2591 |
|
2592 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:131
|
2593 |
+
msgid ""
|
2594 |
+
"Action Scheduler is a scalable, traceable job queue for background "
|
2595 |
+
"processing large sets of actions. Action Scheduler works by triggering an "
|
2596 |
+
"action hook to run at some time in the future. Scheduled actions can also "
|
2597 |
+
"be scheduled to run on a recurring schedule."
|
2598 |
msgstr ""
|
2599 |
|
2600 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:139
|
2601 |
+
msgid "Columns"
|
|
|
|
|
|
|
|
|
|
|
2602 |
msgstr ""
|
2603 |
|
2604 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:141
|
2605 |
+
msgid "Scheduled Action Columns"
|
|
|
|
|
|
|
|
|
2606 |
msgstr ""
|
2607 |
|
2608 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:143
|
2609 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:96
|
2610 |
+
msgid "Hook"
|
|
|
2611 |
msgstr ""
|
2612 |
|
2613 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:143
|
2614 |
+
msgid "Name of the action hook that will be triggered."
|
|
|
2615 |
msgstr ""
|
2616 |
|
2617 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:144
|
2618 |
+
msgid "Action statuses are Pending, Complete, Canceled, Failed"
|
2619 |
msgstr ""
|
2620 |
|
2621 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:145
|
2622 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:98
|
2623 |
+
msgid "Arguments"
|
2624 |
msgstr ""
|
2625 |
|
2626 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:145
|
2627 |
+
msgid "Optional data array passed to the action hook."
|
|
|
|
|
2628 |
msgstr ""
|
2629 |
|
2630 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:146
|
2631 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:99
|
2632 |
+
msgid "Group"
|
|
|
2633 |
msgstr ""
|
2634 |
|
2635 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:146
|
2636 |
+
msgid "Optional action group."
|
|
|
|
|
2637 |
msgstr ""
|
2638 |
|
2639 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:147
|
2640 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:100
|
2641 |
+
msgid "Recurrence"
|
2642 |
msgstr ""
|
2643 |
|
2644 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:147
|
2645 |
+
msgid "The action's schedule frequency."
|
2646 |
msgstr ""
|
2647 |
|
2648 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:148
|
2649 |
+
msgid "Scheduled"
|
2650 |
msgstr ""
|
2651 |
|
2652 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:148
|
2653 |
+
msgid "The date/time the action is/was scheduled to run."
|
2654 |
msgstr ""
|
2655 |
|
2656 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:149
|
2657 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:102
|
2658 |
+
msgid "Log"
|
2659 |
msgstr ""
|
2660 |
|
2661 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_AdminView.php:149
|
2662 |
+
msgid "Activity log for the action."
|
2663 |
msgstr ""
|
2664 |
|
2665 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_DataController.php:133
|
2666 |
+
#. translators: %d: amount of time
|
2667 |
+
msgid "Stopped the insanity for %d second"
|
2668 |
+
msgid_plural "Stopped the insanity for %d seconds"
|
2669 |
+
msgstr[0] ""
|
2670 |
+
msgstr[1] ""
|
2671 |
|
2672 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_DataController.php:137
|
2673 |
+
msgid "Attempting to reduce used memory..."
|
|
|
2674 |
msgstr ""
|
2675 |
|
2676 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_InvalidActionException.php:21
|
2677 |
+
#. translators: 1: action ID 2: schedule
|
2678 |
+
msgid "Action [%1$s] has an invalid schedule: %2$s"
|
2679 |
msgstr ""
|
2680 |
|
2681 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_InvalidActionException.php:40
|
2682 |
+
#. translators: 1: action ID 2: arguments
|
2683 |
+
msgid ""
|
2684 |
+
"Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. "
|
2685 |
+
"$args = %2$s"
|
2686 |
msgstr ""
|
2687 |
|
2688 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:101
|
2689 |
+
msgid "Scheduled Date"
|
|
|
|
|
2690 |
msgstr ""
|
2691 |
|
2692 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:122
|
2693 |
+
msgid "Claim ID"
|
|
|
|
|
2694 |
msgstr ""
|
2695 |
|
2696 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:129
|
2697 |
+
msgid "Run"
|
2698 |
msgstr ""
|
2699 |
|
2700 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:130
|
2701 |
+
msgid "Process the action now as if it were run as part of a queue"
|
2702 |
msgstr ""
|
2703 |
|
2704 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:134
|
2705 |
+
msgid "Cancel the action now to avoid it being run in future"
|
2706 |
msgstr ""
|
2707 |
|
2708 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:144
|
2709 |
+
#. translators: %s: amount of time
|
2710 |
+
msgid "%s year"
|
2711 |
+
msgid_plural "%s years"
|
2712 |
+
msgstr[0] ""
|
2713 |
+
msgstr[1] ""
|
2714 |
|
2715 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:149
|
2716 |
+
#. translators: %s: amount of time
|
2717 |
+
msgid "%s month"
|
2718 |
+
msgid_plural "%s months"
|
2719 |
+
msgstr[0] ""
|
2720 |
+
msgstr[1] ""
|
2721 |
|
2722 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:154
|
2723 |
+
#. translators: %s: amount of time
|
2724 |
+
msgid "%s week"
|
2725 |
+
msgid_plural "%s weeks"
|
2726 |
+
msgstr[0] ""
|
2727 |
+
msgstr[1] ""
|
2728 |
|
2729 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:159
|
2730 |
+
#. translators: %s: amount of time
|
2731 |
+
msgid "%s day"
|
2732 |
+
msgid_plural "%s days"
|
2733 |
+
msgstr[0] ""
|
2734 |
+
msgstr[1] ""
|
2735 |
|
2736 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:164
|
2737 |
+
#. translators: %s: amount of time
|
2738 |
+
msgid "%s hour"
|
2739 |
+
msgid_plural "%s hours"
|
2740 |
+
msgstr[0] ""
|
2741 |
+
msgstr[1] ""
|
2742 |
|
2743 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:169
|
2744 |
+
#. translators: %s: amount of time
|
2745 |
+
msgid "%s minute"
|
2746 |
+
msgid_plural "%s minutes"
|
2747 |
+
msgstr[0] ""
|
2748 |
+
msgstr[1] ""
|
2749 |
|
2750 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:174
|
2751 |
+
#. translators: %s: amount of time
|
2752 |
+
msgid "%s second"
|
2753 |
+
msgid_plural "%s seconds"
|
2754 |
+
msgstr[0] ""
|
2755 |
+
msgstr[1] ""
|
2756 |
|
2757 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:224
|
2758 |
+
msgid "Now!"
|
2759 |
msgstr ""
|
2760 |
|
2761 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:260
|
2762 |
+
#. translators: %s: time interval
|
2763 |
+
msgid "Every %s"
|
2764 |
msgstr ""
|
2765 |
|
2766 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:266
|
2767 |
+
msgid "Non-repeating"
|
|
|
|
|
|
|
|
|
2768 |
msgstr ""
|
2769 |
|
2770 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:364
|
|
|
2771 |
msgid ""
|
2772 |
+
"It appears one or more database tables were missing. Attempting to "
|
2773 |
+
"re-create the missing table(s)."
|
|
|
|
|
2774 |
msgstr ""
|
2775 |
|
2776 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:380
|
2777 |
+
#. translators: %s: amount of claims
|
|
|
2778 |
msgid ""
|
2779 |
+
"Maximum simultaneous queues already in progress (%s queue). No additional "
|
2780 |
+
"queues will begin processing until the current queues are complete."
|
2781 |
msgid_plural ""
|
2782 |
+
"Maximum simultaneous queues already in progress (%s queues). No additional "
|
2783 |
+
"queues will begin processing until the current queues are complete."
|
2784 |
msgstr[0] ""
|
2785 |
msgstr[1] ""
|
2786 |
|
2787 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:397
|
2788 |
+
#. translators: %s: process URL
|
|
|
2789 |
msgid ""
|
2790 |
+
"A new queue has begun processing. <a href=\"%s\">View actions in-progress "
|
2791 |
+
"»</a>"
|
|
|
2792 |
msgstr ""
|
2793 |
|
2794 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:400
|
2795 |
+
#. translators: %d: seconds
|
2796 |
+
msgid "The next queue will begin processing in approximately %d seconds."
|
|
|
|
|
|
|
2797 |
msgstr ""
|
2798 |
|
2799 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:421
|
2800 |
+
#. translators: %s: action HTML
|
2801 |
+
msgid "Successfully executed action: %s"
|
|
|
|
|
|
|
2802 |
msgstr ""
|
2803 |
|
2804 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:425
|
2805 |
+
#. translators: %s: action HTML
|
2806 |
+
msgid "Successfully canceled action: %s"
|
|
|
2807 |
msgstr ""
|
2808 |
|
2809 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:429
|
2810 |
+
#. translators: %s: action HTML
|
2811 |
+
msgid "Successfully processed change for action: %s"
|
2812 |
msgstr ""
|
2813 |
|
2814 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:435
|
2815 |
+
#. translators: 1: action HTML 2: action ID 3: error message
|
2816 |
+
msgid "Could not process change for action: \"%1$s\" (ID: %2$d). Error: %3$s"
|
2817 |
msgstr ""
|
2818 |
|
2819 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:481
|
2820 |
+
#. translators: %s: date interval
|
2821 |
+
msgid " (%s ago)"
|
2822 |
msgstr ""
|
2823 |
|
2824 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:484
|
2825 |
+
#. translators: %s: date interval
|
2826 |
+
msgid " (%s)"
|
2827 |
msgstr ""
|
2828 |
|
2829 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_ListTable.php:634
|
2830 |
+
msgid "Search hook, args and claim ID"
|
2831 |
msgstr ""
|
2832 |
|
2833 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_QueueRunner.php:192
|
2834 |
+
msgid "Every minute"
|
2835 |
msgstr ""
|
2836 |
|
2837 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php:103
|
2838 |
+
#. translators: %s: date interval
|
2839 |
+
msgid "This data will be deleted in %s."
|
2840 |
msgstr ""
|
2841 |
|
2842 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php:108
|
2843 |
+
#. translators: 1: next cleanup message 2: github issue URL
|
2844 |
+
msgid ""
|
2845 |
+
"Action Scheduler has migrated data to custom tables; however, orphaned log "
|
2846 |
+
"entries exist in the WordPress Comments table. %1$s <a href=\"%2$s\">Learn "
|
2847 |
+
"more »</a>"
|
2848 |
msgstr ""
|
2849 |
|
2850 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:111
|
2851 |
+
msgid "Action Scheduler"
|
2852 |
msgstr ""
|
2853 |
|
2854 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:111
|
2855 |
+
msgid "This section shows details of Action Scheduler."
|
2856 |
msgstr ""
|
2857 |
|
2858 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:114
|
2859 |
+
msgid "Version:"
|
2860 |
msgstr ""
|
2861 |
|
2862 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:118
|
2863 |
+
msgid "Data store:"
|
2864 |
msgstr ""
|
2865 |
|
2866 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:122
|
2867 |
+
msgid "Action Status"
|
2868 |
msgstr ""
|
2869 |
|
2870 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:124
|
2871 |
+
msgid "Count"
|
2872 |
msgstr ""
|
2873 |
|
2874 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:125
|
2875 |
+
msgid "Oldest Scheduled Date"
|
2876 |
msgstr ""
|
2877 |
|
2878 |
+
#: vendor/woocommerce/action-scheduler/classes/ActionScheduler_wcSystemStatus.php:126
|
2879 |
+
msgid "Newest Scheduled Date"
|
2880 |
+
msgstr ""
|
2881 |
+
|
2882 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:33
|
2883 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ProgressBar.php:47
|
2884 |
+
#. translators: %s php class name
|
2885 |
+
msgid "The %s class can only be run within WP CLI."
|
2886 |
+
msgstr ""
|
2887 |
+
|
2888 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:59
|
2889 |
+
msgid "There are too many concurrent batches, but the run is forced to continue."
|
2890 |
+
msgstr ""
|
2891 |
+
|
2892 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:61
|
2893 |
+
msgid "There are too many concurrent batches."
|
2894 |
+
msgstr ""
|
2895 |
+
|
2896 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:93
|
2897 |
+
#. translators: %d: amount of actions
|
2898 |
+
msgid "Running %d action"
|
2899 |
+
msgid_plural "Running %d actions"
|
2900 |
+
msgstr[0] ""
|
2901 |
+
msgstr[1] ""
|
2902 |
+
|
2903 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:113
|
2904 |
+
msgid "The claim has been lost. Aborting current batch."
|
2905 |
+
msgstr ""
|
2906 |
+
|
2907 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:138
|
2908 |
+
#. translators: %s refers to the action ID
|
2909 |
+
msgid "Started processing action %s"
|
2910 |
msgstr ""
|
2911 |
|
2912 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:155
|
2913 |
+
#. translators: 1: action ID 2: hook name
|
2914 |
+
msgid "Completed processing action %1$s with hook: %2$s"
|
2915 |
msgstr ""
|
2916 |
|
2917 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php:170
|
2918 |
+
#. translators: 1: action ID 2: exception message
|
2919 |
+
msgid "Error processing action %1$s: %2$s"
|
2920 |
msgstr ""
|
2921 |
|
2922 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php:100
|
2923 |
+
#. translators: %d refers to how many scheduled taks were found to run
|
2924 |
+
msgid "Found %d scheduled task"
|
2925 |
+
msgid_plural "Found %d scheduled tasks"
|
2926 |
+
msgstr[0] ""
|
2927 |
+
msgstr[1] ""
|
2928 |
|
2929 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php:117
|
2930 |
+
#. translators: %d refers to the total number of batches executed
|
2931 |
+
msgid "%d batch executed."
|
2932 |
+
msgid_plural "%d batches executed."
|
2933 |
+
msgstr[0] ""
|
2934 |
+
msgstr[1] ""
|
2935 |
+
|
2936 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php:136
|
2937 |
+
#. translators: %s refers to the exception error message
|
2938 |
+
msgid "There was an error running the action scheduler: %s"
|
2939 |
msgstr ""
|
2940 |
|
2941 |
+
#: vendor/woocommerce/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php:153
|
2942 |
+
#. translators: %d refers to the total number of taskes completed
|
2943 |
+
msgid "%d scheduled task completed."
|
2944 |
+
msgid_plural "%d scheduled tasks completed."
|
2945 |
+
msgstr[0] ""
|
2946 |
+
msgstr[1] ""
|
2947 |
+
|
2948 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler.php:195
|
2949 |
+
msgid "%s() was called before the Action Scheduler data store was initialized"
|
2950 |
msgstr ""
|
2951 |
|
2952 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php:523
|
2953 |
+
msgid "Filter"
|
2954 |
msgstr ""
|
2955 |
|
2956 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php:650
|
2957 |
+
#. translators: %s: search query
|
2958 |
+
msgid "Search results for \"%s\""
|
2959 |
msgstr ""
|
2960 |
|
2961 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php:755
|
2962 |
+
msgid "Search"
|
|
|
2963 |
msgstr ""
|
2964 |
|
2965 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:72
|
2966 |
+
msgid "action created"
|
|
|
|
|
2967 |
msgstr ""
|
2968 |
|
2969 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:76
|
2970 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php:142
|
2971 |
+
msgid "action canceled"
|
2972 |
msgstr ""
|
2973 |
|
2974 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:82
|
2975 |
+
#. translators: %s: context
|
2976 |
+
msgid "action started via %s"
|
|
|
2977 |
msgstr ""
|
2978 |
|
2979 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:84
|
2980 |
+
msgid "action started"
|
|
|
|
|
2981 |
msgstr ""
|
2982 |
|
2983 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:92
|
2984 |
+
#. translators: %s: context
|
2985 |
+
msgid "action complete via %s"
|
|
|
2986 |
msgstr ""
|
2987 |
|
2988 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:94
|
2989 |
+
msgid "action complete"
|
|
|
|
|
2990 |
msgstr ""
|
2991 |
|
2992 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:102
|
2993 |
+
#. translators: 1: context 2: exception message
|
2994 |
+
msgid "action failed via %1$s: %2$s"
|
|
|
2995 |
msgstr ""
|
2996 |
|
2997 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:105
|
2998 |
+
#. translators: %s: exception message
|
2999 |
+
msgid "action failed: %s"
|
|
|
3000 |
msgstr ""
|
3001 |
|
3002 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:112
|
3003 |
+
#. translators: %s: amount of time
|
3004 |
+
msgid "action timed out after %s seconds"
|
|
|
3005 |
msgstr ""
|
3006 |
|
3007 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:118
|
3008 |
+
#. translators: 1: error message 2: filename 3: line
|
3009 |
+
msgid "unexpected shutdown: PHP Fatal error %1$s in %2$s on line %3$s"
|
|
|
3010 |
msgstr ""
|
3011 |
|
3012 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:123
|
3013 |
+
msgid "action reset"
|
|
|
|
|
3014 |
msgstr ""
|
3015 |
|
3016 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:129
|
3017 |
+
#. translators: %s: context
|
3018 |
+
msgid "action ignored via %s"
|
|
|
3019 |
msgstr ""
|
3020 |
|
3021 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:131
|
3022 |
+
msgid "action ignored"
|
|
|
|
|
3023 |
msgstr ""
|
3024 |
|
3025 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:146
|
3026 |
+
#. translators: %s: exception message
|
3027 |
+
msgid "There was a failure fetching this action: %s"
|
|
|
3028 |
msgstr ""
|
3029 |
|
3030 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:148
|
3031 |
+
msgid "There was a failure fetching this action"
|
|
|
|
|
3032 |
msgstr ""
|
3033 |
|
3034 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Logger.php:156
|
3035 |
+
#. translators: %s: exception message
|
3036 |
+
msgid "There was a failure scheduling the next instance of this action: %s"
|
3037 |
msgstr ""
|
3038 |
|
3039 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:301
|
3040 |
msgid ""
|
3041 |
+
"ActionScheduler_Action::$args too long. To ensure the args column can be "
|
3042 |
+
"indexed, action args should not be more than %d characters when encoded as "
|
3043 |
+
"JSON."
|
3044 |
msgstr ""
|
3045 |
|
3046 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:377
|
3047 |
+
msgid "Complete"
|
3048 |
msgstr ""
|
3049 |
|
3050 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:379
|
3051 |
+
msgid "In-progress"
|
|
|
|
|
3052 |
msgstr ""
|
3053 |
|
3054 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:380
|
3055 |
+
msgid "Failed"
|
3056 |
msgstr ""
|
3057 |
|
3058 |
+
#: vendor/woocommerce/action-scheduler/classes/abstracts/ActionScheduler_Store.php:381
|
3059 |
+
msgid "Canceled"
|
3060 |
msgstr ""
|
3061 |
|
3062 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:78
|
3063 |
+
msgid "Database error."
|
3064 |
msgstr ""
|
3065 |
|
3066 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:86
|
3067 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:49
|
3068 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php:44
|
3069 |
+
#. translators: %s: error message
|
3070 |
+
#. translators: %s: action error message
|
3071 |
+
msgid "Error saving action: %s"
|
3072 |
msgstr ""
|
3073 |
|
3074 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:246
|
3075 |
+
msgid "Invalid value for select or count parameter. Cannot query actions."
|
3076 |
msgstr ""
|
3077 |
|
3078 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:451
|
3079 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:543
|
3080 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:574
|
3081 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:797
|
3082 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:840
|
3083 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:515
|
3084 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:534
|
3085 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:564
|
3086 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:974
|
3087 |
+
#. translators: %s: action ID
|
3088 |
+
#. translators: %s is the action ID
|
3089 |
+
msgid "Unidentified action %s"
|
3090 |
msgstr ""
|
3091 |
|
3092 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:663
|
3093 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:717
|
3094 |
+
#. translators: %s: group name
|
3095 |
+
#. translators: %s is the group name
|
3096 |
+
msgid "The group \"%s\" does not exist."
|
3097 |
msgstr ""
|
3098 |
|
3099 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:683
|
3100 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:696
|
3101 |
+
msgid "Unable to claim actions. Database error."
|
|
|
|
|
3102 |
msgstr ""
|
3103 |
|
3104 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:861
|
3105 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:904
|
3106 |
+
msgid "Invalid action ID. No status found."
|
|
|
|
|
3107 |
msgstr ""
|
3108 |
|
3109 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php:863
|
3110 |
+
msgid "Unknown status found for action."
|
3111 |
msgstr ""
|
3112 |
|
3113 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:101
|
3114 |
+
msgid "Unable to save action."
|
3115 |
msgstr ""
|
3116 |
|
3117 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:318
|
3118 |
+
msgid "Invalid schedule. Cannot save action."
|
3119 |
msgstr ""
|
3120 |
|
3121 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:824
|
3122 |
+
#. translators: %s: claim ID
|
3123 |
+
msgid "Unable to unlock claim %s. Database error."
|
3124 |
msgstr ""
|
3125 |
|
3126 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:852
|
3127 |
+
#. translators: %s: action ID
|
3128 |
+
msgid "Unable to unlock claim on action %s. Database error."
|
3129 |
msgstr ""
|
3130 |
|
3131 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:878
|
3132 |
+
#. translators: %s: action ID
|
3133 |
+
msgid "Unable to mark failure on action %s. Database error."
|
3134 |
msgstr ""
|
3135 |
|
3136 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php:1046
|
3137 |
+
#. translators: %s is the error message
|
3138 |
+
msgid "%s Support for strings longer than this will be removed in a future version."
|
3139 |
msgstr ""
|
3140 |
|
3141 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php:38
|
3142 |
+
#. translators: %s: count
|
3143 |
+
msgid "Failed <span class=\"count\">(%s)</span>"
|
3144 |
+
msgid_plural "Failed <span class=\"count\">(%s)</span>"
|
3145 |
+
msgstr[0] ""
|
3146 |
+
msgstr[1] ""
|
3147 |
+
|
3148 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php:53
|
3149 |
+
#. translators: %s: count
|
3150 |
+
msgid "In-Progress <span class=\"count\">(%s)</span>"
|
3151 |
+
msgid_plural "In-Progress <span class=\"count\">(%s)</span>"
|
3152 |
+
msgstr[0] ""
|
3153 |
+
msgstr[1] ""
|
3154 |
+
|
3155 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:20
|
3156 |
+
msgid "Scheduled actions are hooks triggered on a cetain date and time."
|
3157 |
msgstr ""
|
3158 |
|
3159 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:31
|
3160 |
+
msgid "Scheduled Action"
|
3161 |
msgstr ""
|
3162 |
|
3163 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:33
|
3164 |
+
msgid "Add"
|
|
|
|
|
3165 |
msgstr ""
|
3166 |
|
3167 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:34
|
3168 |
+
msgid "Add New Scheduled Action"
|
3169 |
msgstr ""
|
3170 |
|
3171 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:36
|
3172 |
+
msgid "Edit Scheduled Action"
|
3173 |
msgstr ""
|
3174 |
|
3175 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:37
|
3176 |
+
msgid "New Scheduled Action"
|
|
|
|
|
3177 |
msgstr ""
|
3178 |
|
3179 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:38
|
3180 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:39
|
3181 |
+
msgid "View Action"
|
3182 |
msgstr ""
|
3183 |
|
3184 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:40
|
3185 |
+
msgid "Search Scheduled Actions"
|
|
|
3186 |
msgstr ""
|
3187 |
|
3188 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:41
|
3189 |
+
msgid "No actions found"
|
3190 |
msgstr ""
|
3191 |
|
3192 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:42
|
3193 |
+
msgid "No actions found in trash"
|
3194 |
msgstr ""
|
3195 |
|
3196 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php:14
|
3197 |
+
msgid "Action Group"
|
3198 |
msgstr ""
|
3199 |
|
3200 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/ActionMigrator.php:95
|
3201 |
+
msgid "Unable to remove source migrated action %s"
|
3202 |
msgstr ""
|
3203 |
|
3204 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Config.php:52
|
3205 |
+
msgid "Source store must be configured before running a migration"
|
3206 |
msgstr ""
|
3207 |
|
3208 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Config.php:74
|
3209 |
+
msgid "Source logger must be configured before running a migration"
|
3210 |
msgstr ""
|
3211 |
|
3212 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Config.php:96
|
3213 |
+
msgid "Destination store must be configured before running a migration"
|
|
|
|
|
3214 |
msgstr ""
|
3215 |
|
3216 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Config.php:118
|
3217 |
+
msgid "Destination logger must be configured before running a migration"
|
3218 |
msgstr ""
|
3219 |
|
3220 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Controller.php:162
|
3221 |
msgid ""
|
3222 |
+
"Action Scheduler migration in progress. The list of scheduled actions may "
|
3223 |
+
"be incomplete."
|
3224 |
msgstr ""
|
3225 |
|
3226 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Runner.php:82
|
3227 |
+
#. translators: %d: amount of actions
|
3228 |
+
msgid "Migrating %d action"
|
3229 |
+
msgid_plural "Migrating %d actions"
|
3230 |
+
msgstr[0] ""
|
3231 |
+
msgstr[1] ""
|
3232 |
+
|
3233 |
+
#: vendor/woocommerce/action-scheduler/classes/migration/Runner.php:107
|
3234 |
+
#. translators: 1: source action ID 2: source store class 3: destination action
|
3235 |
+
#. ID 4: destination store class
|
3236 |
+
msgid "Migrated action with ID %1$d in %2$s to ID %3$d in %4$s"
|
3237 |
msgstr ""
|
3238 |
|
3239 |
#. Plugin URI of the plugin/theme
|
3250 |
msgid "https://www.woocommerce.com/"
|
3251 |
msgstr ""
|
3252 |
|
3253 |
+
#: includes/Admin/Sync_Page.php:286
|
3254 |
msgctxt "Delete all records"
|
3255 |
msgid "Clear history"
|
3256 |
msgstr ""
|
3257 |
|
3258 |
+
#: includes/Admin/Sync_Page.php:291 includes/Admin/Sync_Page.php:332
|
3259 |
msgctxt "Date - Time"
|
3260 |
msgid "Time"
|
3261 |
msgstr ""
|
3262 |
|
3263 |
+
#: includes/Emails/Access_Token_Email.php:45
|
3264 |
msgctxt "Email subject"
|
3265 |
msgid "[WooCommerce] There was a problem with your Square Access Token"
|
3266 |
msgstr ""
|
3267 |
|
3268 |
+
#: includes/Emails/Sync_Completed.php:35
|
3269 |
msgctxt "Email subject"
|
3270 |
msgid "[WooCommerce] Square sync completed"
|
3271 |
msgstr ""
|
3272 |
|
3273 |
+
#: includes/Emails/Access_Token_Email.php:46
|
3274 |
msgctxt "Email heading"
|
3275 |
msgid "There was a problem with your Square Access Token"
|
3276 |
msgstr ""
|
3277 |
|
3278 |
+
#: includes/Emails/Access_Token_Email.php:47
|
3279 |
msgctxt "Square connection problems email body."
|
3280 |
msgid "Heads up! There may be a problem with your connection to Square."
|
3281 |
msgstr ""
|
3282 |
|
3283 |
+
#: includes/Emails/Sync_Completed.php:36
|
3284 |
msgctxt "Email heading with merge tag placeholder"
|
3285 |
msgid "Square sync completed for {product_count}"
|
3286 |
msgstr ""
|
3287 |
|
3288 |
+
#: includes/Emails/Sync_Completed.php:37
|
3289 |
msgctxt "Email body with merge tag placeholders"
|
3290 |
msgid ""
|
3291 |
"Square sync completed for {site_title} at {sync_completed_date} "
|
3292 |
"{sync_completed_time}."
|
3293 |
msgstr ""
|
3294 |
|
3295 |
+
#: includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php:545
|
3296 |
+
msgctxt "hash before order number"
|
3297 |
+
msgid "#%s"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3298 |
msgstr ""
|
3299 |
|
3300 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2155
|
3301 |
+
msgctxt "hash before order number"
|
3302 |
+
msgid "#"
|
3303 |
msgstr ""
|
3304 |
|
3305 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2360
|
3306 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:565
|
3307 |
msgctxt "noun, software environment"
|
3308 |
msgid "Test"
|
3309 |
msgstr ""
|
3310 |
|
3311 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2361
|
3312 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2761
|
3313 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:566
|
3314 |
msgctxt "credit card transaction type"
|
3315 |
msgid "Authorization"
|
3316 |
msgstr ""
|
3317 |
|
3318 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2361
|
3319 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2760
|
3320 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Direct.php:566
|
3321 |
msgctxt "noun, credit card transaction type"
|
3322 |
msgid "Charge"
|
3323 |
msgstr ""
|
3324 |
|
3325 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:2789
|
3326 |
+
msgctxt ""
|
3327 |
+
"coordinating conjunction for a list of order statuses: on-hold, processing, "
|
3328 |
+
"or completed"
|
3329 |
+
msgid "or"
|
3330 |
msgstr ""
|
3331 |
|
3332 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3019
|
3333 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:201
|
3334 |
msgctxt "credit card type"
|
3335 |
msgid "Visa"
|
3336 |
msgstr ""
|
3337 |
|
3338 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3020
|
3339 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:205
|
3340 |
msgctxt "credit card type"
|
3341 |
msgid "MasterCard"
|
3342 |
msgstr ""
|
3343 |
|
3344 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3021
|
3345 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:209
|
3346 |
msgctxt "credit card type"
|
3347 |
msgid "American Express"
|
3348 |
msgstr ""
|
3349 |
|
3350 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3022
|
3351 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:217
|
3352 |
msgctxt "credit card type"
|
3353 |
+
msgid "Discover"
|
3354 |
msgstr ""
|
3355 |
|
3356 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3023
|
|
|
3357 |
msgctxt "credit card type"
|
3358 |
+
msgid "Diners"
|
3359 |
msgstr ""
|
3360 |
|
3361 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3024
|
3362 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:221
|
3363 |
msgctxt "credit card type"
|
3364 |
msgid "JCB"
|
3365 |
msgstr ""
|
3366 |
|
3367 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:213
|
3368 |
+
msgctxt "credit card type"
|
3369 |
+
msgid "Diners Club"
|
3370 |
+
msgstr ""
|
3371 |
+
|
3372 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:225
|
3373 |
msgctxt "credit card type"
|
3374 |
msgid "CarteBleue"
|
3375 |
msgstr ""
|
3376 |
|
3377 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:229
|
3378 |
msgctxt "credit card type"
|
3379 |
msgid "Maestro"
|
3380 |
msgstr ""
|
3381 |
|
3382 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:233
|
3383 |
msgctxt "credit card type"
|
3384 |
msgid "Laser"
|
3385 |
msgstr ""
|
3386 |
|
3387 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway.php:3509
|
3388 |
+
msgctxt "software environment"
|
3389 |
+
msgid "Production"
|
3390 |
msgstr ""
|
3391 |
|
3392 |
+
#: includes/Framework/PaymentGateway/Payment_Gateway_Helper.php:165
|
3393 |
+
msgctxt "payment method type"
|
3394 |
+
msgid "Account"
|
|
|
3395 |
msgstr ""
|
3396 |
|
3397 |
+
#: includes/Framework/Plugin.php:353
|
3398 |
+
msgctxt "noun"
|
3399 |
+
msgid "Support"
|
|
|
3400 |
msgstr ""
|
3401 |
|
3402 |
+
#: includes/Framework/Plugin.php:358
|
3403 |
+
msgctxt "verb"
|
3404 |
+
msgid "Review"
|
3405 |
msgstr ""
|
3406 |
|
3407 |
+
#: includes/Framework/Square_Helper.php:218
|
3408 |
+
#: includes/Utilities/Array_Utility.php:90
|
3409 |
+
msgctxt "coordinating conjunction for a list of items: a, b, and c"
|
3410 |
+
msgid "and"
|
3411 |
msgstr ""
|
3412 |
|
3413 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php:36
|
3414 |
+
msgctxt "post"
|
3415 |
+
msgid "Failed"
|
|
|
|
|
3416 |
msgstr ""
|
3417 |
|
3418 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php:51
|
3419 |
+
msgctxt "post"
|
3420 |
+
msgid "In-Progress"
|
3421 |
+
msgstr ""
|
3422 |
+
|
3423 |
+
#: vendor/woocommerce/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php:32
|
3424 |
+
msgctxt "Admin menu name"
|
3425 |
+
msgid "Scheduled Actions"
|
3426 |
msgstr ""
|
includes/AJAX.php
CHANGED
@@ -25,9 +25,7 @@ namespace WooCommerce\Square;
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
30 |
-
use WooCommerce\Square\Handlers\Sync;
|
31 |
use WooCommerce\Square\Sync\Records;
|
32 |
|
33 |
/**
|
@@ -63,41 +61,6 @@ class AJAX {
|
|
63 |
add_action( 'wp_ajax_wc_square_get_sync_with_square_status', array( $this, 'get_sync_with_square_job_status' ) );
|
64 |
}
|
65 |
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Checks if a product is set to be synced with Square.
|
69 |
-
*
|
70 |
-
* @internal
|
71 |
-
*
|
72 |
-
* @since 2.0.0
|
73 |
-
*
|
74 |
-
* @deprecated 2.1.6
|
75 |
-
*/
|
76 |
-
public function is_product_synced_with_square() {
|
77 |
-
_deprecated_function( 'is_product_synced_with_square', '2.1.6', 'get_quick_edit_product_details' );
|
78 |
-
|
79 |
-
check_ajax_referer( 'is-product-synced-with-square', 'security' );
|
80 |
-
|
81 |
-
if ( isset( $_POST['product_id'] ) && ( $product = wc_get_product( $_POST['product_id'] ) ) ) {
|
82 |
-
|
83 |
-
if ( $product->is_type( 'variable' ) && $product->has_child() ) {
|
84 |
-
if ( Product::has_multiple_variation_attributes( $product ) ) {
|
85 |
-
wp_send_json_error( 'multiple_attributes' );
|
86 |
-
} elseif ( ! Product::has_sku( $product ) ) {
|
87 |
-
wp_send_json_error( 'missing_variation_sku' );
|
88 |
-
}
|
89 |
-
} else {
|
90 |
-
if ( ! Product::has_sku( $product ) ) {
|
91 |
-
wp_send_json_error( 'missing_sku' );
|
92 |
-
}
|
93 |
-
}
|
94 |
-
wp_send_json_success( Product::is_synced_with_square( $product ) ? 'yes' : 'no' );
|
95 |
-
}
|
96 |
-
|
97 |
-
wp_send_json_error( 'invalid_product' );
|
98 |
-
}
|
99 |
-
|
100 |
-
|
101 |
/**
|
102 |
* Fetches product stock data from Square.
|
103 |
*
|
@@ -119,7 +82,7 @@ class AJAX {
|
|
119 |
|
120 |
wp_send_json_success( $product->get_stock_quantity() );
|
121 |
|
122 |
-
} catch (
|
123 |
|
124 |
/* translators: Placeholders: %1$s = error message, %2$s = help text */
|
125 |
wp_send_json_error( sprintf( __( 'Unable to fetch inventory: %1$s. %2$s', 'woocommerce-square' ), $exception->getMessage(), $fix_error ) );
|
@@ -142,7 +105,7 @@ class AJAX {
|
|
142 |
|
143 |
check_ajax_referer( 'import-products-from-square', 'security' );
|
144 |
|
145 |
-
$started = wc_square()->get_sync_handler()->start_product_import(
|
146 |
|
147 |
if ( ! $started ) {
|
148 |
wp_send_json_error( __( 'Could not start import. Please try again.', 'woocommerce-square' ) );
|
@@ -163,7 +126,7 @@ class AJAX {
|
|
163 |
|
164 |
check_ajax_referer( 'sync-products-with-square', 'security' );
|
165 |
|
166 |
-
$started = wc_square()->get_sync_handler()->start_manual_sync(
|
167 |
|
168 |
if ( ! $started ) {
|
169 |
wp_send_json_error();
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
|
|
28 |
use WooCommerce\Square\Handlers\Product;
|
|
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
31 |
/**
|
61 |
add_action( 'wp_ajax_wc_square_get_sync_with_square_status', array( $this, 'get_sync_with_square_job_status' ) );
|
62 |
}
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
/**
|
65 |
* Fetches product stock data from Square.
|
66 |
*
|
82 |
|
83 |
wp_send_json_success( $product->get_stock_quantity() );
|
84 |
|
85 |
+
} catch ( \Exception $exception ) {
|
86 |
|
87 |
/* translators: Placeholders: %1$s = error message, %2$s = help text */
|
88 |
wp_send_json_error( sprintf( __( 'Unable to fetch inventory: %1$s. %2$s', 'woocommerce-square' ), $exception->getMessage(), $fix_error ) );
|
105 |
|
106 |
check_ajax_referer( 'import-products-from-square', 'security' );
|
107 |
|
108 |
+
$started = wc_square()->get_sync_handler()->start_product_import( ( ! empty( $_POST['update_during_import'] ) && 'true' === $_POST['update_during_import'] ) );
|
109 |
|
110 |
if ( ! $started ) {
|
111 |
wp_send_json_error( __( 'Could not start import. Please try again.', 'woocommerce-square' ) );
|
126 |
|
127 |
check_ajax_referer( 'sync-products-with-square', 'security' );
|
128 |
|
129 |
+
$started = wc_square()->get_sync_handler()->start_manual_sync();
|
130 |
|
131 |
if ( ! $started ) {
|
132 |
wp_send_json_error();
|
includes/API.php
CHANGED
@@ -23,10 +23,11 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
-
use
|
27 |
-
use SquareConnect;
|
28 |
use WooCommerce\Square\API\Requests;
|
29 |
use WooCommerce\Square\API\Responses;
|
|
|
|
|
30 |
|
31 |
defined( 'ABSPATH' ) || exit;
|
32 |
|
@@ -35,7 +36,7 @@ defined( 'ABSPATH' ) || exit;
|
|
35 |
*
|
36 |
* @since 2.0.0
|
37 |
*/
|
38 |
-
class API extends
|
39 |
|
40 |
|
41 |
/** catalog request type */
|
@@ -45,7 +46,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
45 |
const REQUEST_TYPE_INVENTORY = 'inventory';
|
46 |
|
47 |
|
48 |
-
/** @var
|
49 |
protected $client;
|
50 |
|
51 |
|
@@ -58,15 +59,10 @@ class API extends Framework\SV_WC_API_Base {
|
|
58 |
* @param bool $is_sandbox If sandbox access is desired
|
59 |
*/
|
60 |
public function __construct( $access_token, $is_sandbox = null ) {
|
61 |
-
$
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
if ( $is_sandbox ) {
|
66 |
-
$api_config->setHost( 'https://connect.squareupsandbox.com' );
|
67 |
-
}
|
68 |
-
|
69 |
-
$this->client = new SquareConnect\ApiClient( $api_config );
|
70 |
}
|
71 |
|
72 |
|
@@ -80,7 +76,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
80 |
*
|
81 |
* @param string[] $object_ids array of square catalog object IDs
|
82 |
* @return Responses\Catalog
|
83 |
-
* @throws
|
84 |
*/
|
85 |
public function batch_delete_catalog_objects( array $object_ids ) {
|
86 |
|
@@ -99,7 +95,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
99 |
* @param string[] $object_ids array of square catalog object IDs
|
100 |
* @param bool $include_related_objects whether or not to include related objects in the response
|
101 |
* @return Responses\Catalog
|
102 |
-
* @throws
|
103 |
*/
|
104 |
public function batch_retrieve_catalog_objects( array $object_ids, $include_related_objects = false ) {
|
105 |
|
@@ -118,7 +114,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
118 |
* @param string $idempotency_key a UUID for this request
|
119 |
* @param array $batches an array of batches to upsert
|
120 |
* @return Responses\Catalog
|
121 |
-
* @throws
|
122 |
*/
|
123 |
public function batch_upsert_catalog_objects( $idempotency_key, array $batches ) {
|
124 |
|
@@ -134,7 +130,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
134 |
*
|
135 |
* @since 2.0.0
|
136 |
* @return Responses\Catalog
|
137 |
-
* @throws
|
138 |
*/
|
139 |
public function catalog_info() {
|
140 |
|
@@ -152,7 +148,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
152 |
*
|
153 |
* @param string $object_id Square catalog object ID
|
154 |
* @return Responses\Catalog
|
155 |
-
* @throws
|
156 |
*/
|
157 |
public function delete_catalog_object( $object_id ) {
|
158 |
|
@@ -171,7 +167,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
171 |
* @param string $cursor the cursor to list from
|
172 |
* @param string[] $types the item types to filter by
|
173 |
* @return Responses\Catalog
|
174 |
-
* @throws
|
175 |
*/
|
176 |
public function list_catalog( $cursor = '', $types = array() ) {
|
177 |
|
@@ -190,7 +186,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
190 |
* @param string $object_id the Square catalog object ID
|
191 |
* @param bool $include_related_objects whether or not to include related objects (such as categories)
|
192 |
* @return Responses\Catalog
|
193 |
-
* @throws
|
194 |
*/
|
195 |
public function retrieve_catalog_object( $object_id, $include_related_objects = false ) {
|
196 |
|
@@ -208,7 +204,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
208 |
*
|
209 |
* @param array $args see Catalog::set_search_catalog_objects_data() for list of args
|
210 |
* @return Responses\Catalog
|
211 |
-
* @throws
|
212 |
*/
|
213 |
public function search_catalog_objects( $args = array() ) {
|
214 |
|
@@ -228,7 +224,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
228 |
* @param string[] $modifier_lists_to_enable (optional) modifier list IDs to enable
|
229 |
* @param string[] $modifier_lists_to_disable (optional) modifier list IDs to disable
|
230 |
* @return Responses\Catalog
|
231 |
-
* @throws
|
232 |
*/
|
233 |
public function update_item_modifier_lists( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
234 |
|
@@ -248,7 +244,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
248 |
* @param string[] $taxes_to_enable (optional) tax IDs to enable
|
249 |
* @param string[] $taxes_to_disable (optional) tax IDs to disable
|
250 |
* @return Responses\Catalog
|
251 |
-
* @throws
|
252 |
*/
|
253 |
public function update_item_taxes( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
254 |
|
@@ -265,9 +261,9 @@ class API extends Framework\SV_WC_API_Base {
|
|
265 |
* @since 2.0.0
|
266 |
*
|
267 |
* @param string $idempotency_key UUID for this request
|
268 |
-
* @param
|
269 |
* @return Responses\Catalog
|
270 |
-
* @throws
|
271 |
*/
|
272 |
public function upsert_catalog_object( $idempotency_key, $object ) {
|
273 |
|
@@ -289,12 +285,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
289 |
* @param string $square_item_id
|
290 |
* @param string $caption optional image caption
|
291 |
* @return string
|
292 |
-
* @throws
|
293 |
*/
|
294 |
public function create_image( $image_path, $square_item_id = '', $caption = '' ) {
|
295 |
|
296 |
if ( ! is_readable( $image_path ) ) {
|
297 |
-
throw new
|
298 |
}
|
299 |
|
300 |
$image = file_get_contents( $image_path );
|
@@ -335,7 +331,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
335 |
$body .= $image . "\r\n";
|
336 |
$body .= '--boundary--';
|
337 |
|
338 |
-
$url = $this->client->
|
339 |
|
340 |
$response = wp_remote_post(
|
341 |
$url,
|
@@ -346,14 +342,14 @@ class API extends Framework\SV_WC_API_Base {
|
|
346 |
);
|
347 |
|
348 |
if ( is_wp_error( $response ) ) {
|
349 |
-
throw new
|
350 |
}
|
351 |
|
352 |
$body = wp_remote_retrieve_body( $response );
|
353 |
$body = json_decode( $body, true );
|
354 |
|
355 |
if ( ! is_array( $body ) ) {
|
356 |
-
throw new
|
357 |
}
|
358 |
|
359 |
if ( ! empty( $body['errors'] ) || empty( $body['image']['id'] ) ) {
|
@@ -364,7 +360,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
364 |
$message = 'Unknown error';
|
365 |
}
|
366 |
|
367 |
-
throw new
|
368 |
}
|
369 |
|
370 |
return $body['image']['id'];
|
@@ -382,7 +378,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
382 |
* @param string $square_id Square object ID
|
383 |
* @param int $amount amount of inventory to add
|
384 |
* @return Responses\Inventory
|
385 |
-
* @throws
|
386 |
*/
|
387 |
public function add_inventory_from_refund( $square_id, $amount ) {
|
388 |
|
@@ -399,7 +395,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
399 |
* @param int $amount amount of inventory to add
|
400 |
* @param string $from_state the API state the inventory is coming from
|
401 |
* @return Responses\Inventory
|
402 |
-
* @throws
|
403 |
*/
|
404 |
public function add_inventory( $square_id, $amount, $from_state = 'NONE' ) {
|
405 |
|
@@ -415,7 +411,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
415 |
* @param string $square_id Square object ID
|
416 |
* @param int $amount amount of inventory to remove
|
417 |
* @return Responses\Inventory
|
418 |
-
* @throws
|
419 |
*/
|
420 |
public function remove_inventory( $square_id, $amount ) {
|
421 |
|
@@ -433,26 +429,24 @@ class API extends Framework\SV_WC_API_Base {
|
|
433 |
* @param string $from_state the API state the inventory is coming from
|
434 |
* @param string $to_state the API state the inventory is changing to
|
435 |
* @return Responses\Inventory
|
436 |
-
* @throws
|
437 |
*/
|
438 |
protected function adjust_inventory( $square_id, $amount, $from_state, $to_state ) {
|
439 |
|
440 |
$date = new \DateTime();
|
441 |
|
442 |
-
$change = new
|
443 |
$change->setType( 'ADJUSTMENT' );
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
)
|
455 |
-
);
|
456 |
|
457 |
return $this->batch_change_inventory(
|
458 |
uniqid( '', false ),
|
@@ -469,10 +463,10 @@ class API extends Framework\SV_WC_API_Base {
|
|
469 |
* @since 2.0.0
|
470 |
*
|
471 |
* @param string $idempotency_key UUID for this request
|
472 |
-
* @param
|
473 |
* @param bool $ignore_unchanged_counts whether the current physical count should be ignored if the quantity is unchanged since the last physical count
|
474 |
* @return Responses\Inventory
|
475 |
-
* @throws
|
476 |
*/
|
477 |
public function batch_change_inventory( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
478 |
|
@@ -491,7 +485,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
491 |
* @param array $args see Requests\Inventory::set_batch_retrieve_inventory_changes_data() for accepted arguments
|
492 |
*
|
493 |
* @return Responses\Inventory
|
494 |
-
* @throws
|
495 |
*/
|
496 |
public function batch_retrieve_inventory_changes( array $args = array() ) {
|
497 |
|
@@ -510,7 +504,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
510 |
* @param array $args see Requests\Inventory::set_batch_retrieve_inventory_counts_data() for accepted arguments
|
511 |
*
|
512 |
* @return Responses\Inventory
|
513 |
-
* @throws
|
514 |
*/
|
515 |
public function batch_retrieve_inventory_counts( array $args = array() ) {
|
516 |
|
@@ -529,7 +523,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
529 |
* @param string $adjustment_id the InventoryAdjustment ID to retrieve
|
530 |
*
|
531 |
* @return Responses\Inventory
|
532 |
-
* @throws
|
533 |
*/
|
534 |
public function retrieve_inventory_adjustment( $adjustment_id ) {
|
535 |
|
@@ -548,7 +542,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
548 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
549 |
*
|
550 |
* @return Responses\Inventory
|
551 |
-
* @throws
|
552 |
*/
|
553 |
public function retrieve_inventory_changes( $catalog_object_id ) {
|
554 |
|
@@ -566,12 +560,12 @@ class API extends Framework\SV_WC_API_Base {
|
|
566 |
*
|
567 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
568 |
* @return Responses\Inventory
|
569 |
-
* @throws
|
570 |
*/
|
571 |
public function retrieve_inventory_count( $catalog_object_id ) {
|
572 |
|
573 |
$request = $this->get_inventory_request();
|
574 |
-
$request->set_retrieve_inventory_count_data( $catalog_object_id,
|
575 |
|
576 |
return $this->perform_request( $request );
|
577 |
}
|
@@ -585,7 +579,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
585 |
* @param string $physical_count_id the InventoryPhysicalCount ID to retrieve
|
586 |
*
|
587 |
* @return Responses\Inventory
|
588 |
-
* @throws
|
589 |
*/
|
590 |
public function retrieve_inventory_physical_count( $physical_count_id ) {
|
591 |
|
@@ -604,8 +598,8 @@ class API extends Framework\SV_WC_API_Base {
|
|
604 |
*
|
605 |
* @since 2.0.0
|
606 |
*
|
607 |
-
* @return
|
608 |
-
* @throws
|
609 |
*/
|
610 |
public function get_locations() {
|
611 |
|
@@ -632,7 +626,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
632 |
*
|
633 |
* @param string $cursor pagination cursor
|
634 |
* @return API\Response
|
635 |
-
* @throws
|
636 |
*/
|
637 |
public function get_customers( $cursor = '' ) {
|
638 |
|
@@ -655,7 +649,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
655 |
* @since 2.0.0
|
656 |
*
|
657 |
* @return Requests\Catalog
|
658 |
-
* @throws
|
659 |
*/
|
660 |
protected function get_catalog_request() {
|
661 |
|
@@ -669,7 +663,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
669 |
* @since 2.0.0
|
670 |
*
|
671 |
* @return Requests\Inventory
|
672 |
-
* @throws
|
673 |
*/
|
674 |
protected function get_inventory_request() {
|
675 |
|
@@ -684,7 +678,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
684 |
*
|
685 |
* @param string $type desired request type
|
686 |
* @return Requests\Catalog|Requests\Inventory
|
687 |
-
* @throws
|
688 |
*/
|
689 |
protected function get_new_request( $type = '' ) {
|
690 |
|
@@ -701,7 +695,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
701 |
break;
|
702 |
|
703 |
default:
|
704 |
-
throw new
|
705 |
}
|
706 |
|
707 |
$this->set_response_handler( $response_handler );
|
@@ -713,13 +707,13 @@ class API extends Framework\SV_WC_API_Base {
|
|
713 |
/**
|
714 |
* Performs an API request.
|
715 |
*
|
716 |
-
* @see
|
717 |
*
|
718 |
* @since 2.0.0
|
719 |
*
|
720 |
* @param API\Request $request request object
|
721 |
-
* @return
|
722 |
-
* @throws
|
723 |
*/
|
724 |
protected function perform_request( $request ) {
|
725 |
|
@@ -754,7 +748,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
754 |
// parse & validate response
|
755 |
$response = $this->handle_response( $response );
|
756 |
|
757 |
-
} catch (
|
758 |
|
759 |
// alert other actors that a request has been made
|
760 |
$this->broadcast_request();
|
@@ -772,14 +766,10 @@ class API extends Framework\SV_WC_API_Base {
|
|
772 |
* @since 2.0.0
|
773 |
*
|
774 |
* @param array|\WP_Error $response response data
|
775 |
-
* @throws
|
776 |
-
* @return
|
777 |
*/
|
778 |
protected function handle_response( $response ) {
|
779 |
-
|
780 |
-
// allow child classes to validate response prior to parsing
|
781 |
-
$this->do_pre_parse_response_validation();
|
782 |
-
|
783 |
// parse the response body and tie it to the request
|
784 |
$this->response = $this->get_parsed_response( $this->raw_response_body );
|
785 |
|
@@ -801,7 +791,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
801 |
* @since 2.0.0
|
802 |
*
|
803 |
* @return bool
|
804 |
-
* @throws
|
805 |
*/
|
806 |
protected function do_post_parse_response_validation() {
|
807 |
|
@@ -840,7 +830,7 @@ class API extends Framework\SV_WC_API_Base {
|
|
840 |
}
|
841 |
|
842 |
// At this point we could not validate the response and assume a failed attempt.
|
843 |
-
throw new
|
844 |
}
|
845 |
|
846 |
/**
|
@@ -851,31 +841,26 @@ class API extends Framework\SV_WC_API_Base {
|
|
851 |
* @param Object $square_api the square API class instance
|
852 |
* @param string $method the class method to call
|
853 |
* @param array $args the args to send with the method call
|
854 |
-
* @throws
|
855 |
*/
|
856 |
protected function do_square_request( $square_api, $method, $args ) {
|
857 |
|
858 |
if ( ! is_callable( array( $square_api, $method ) ) ) {
|
859 |
-
throw new
|
860 |
}
|
861 |
|
862 |
-
|
|
|
863 |
|
864 |
-
|
865 |
-
$
|
|
|
866 |
|
867 |
-
if (
|
868 |
-
$this->
|
869 |
-
$this->response_headers = isset( $response[2] ) ? (array) $response[2] : array();
|
870 |
-
$this->raw_response_body = isset( $response[0] ) ? $response[0] : array();
|
871 |
} else {
|
872 |
-
$this->raw_response_body = $response;
|
873 |
}
|
874 |
-
} catch ( SquareConnect\ApiException $exception ) {
|
875 |
-
|
876 |
-
$this->response_code = $exception->getCode();
|
877 |
-
$this->response_headers = $exception->getResponseHeaders();
|
878 |
-
$this->raw_response_body = $exception->getResponseBody();
|
879 |
}
|
880 |
}
|
881 |
|
23 |
|
24 |
namespace WooCommerce\Square;
|
25 |
|
26 |
+
use WooCommerce\Square\Framework\Api\Base;
|
|
|
27 |
use WooCommerce\Square\API\Requests;
|
28 |
use WooCommerce\Square\API\Responses;
|
29 |
+
use Square\SquareClient;
|
30 |
+
use Square\Environment;
|
31 |
|
32 |
defined( 'ABSPATH' ) || exit;
|
33 |
|
36 |
*
|
37 |
* @since 2.0.0
|
38 |
*/
|
39 |
+
class API extends Base {
|
40 |
|
41 |
|
42 |
/** catalog request type */
|
46 |
const REQUEST_TYPE_INVENTORY = 'inventory';
|
47 |
|
48 |
|
49 |
+
/** @var \Square\SquareClient Square API client instance */
|
50 |
protected $client;
|
51 |
|
52 |
|
59 |
* @param bool $is_sandbox If sandbox access is desired
|
60 |
*/
|
61 |
public function __construct( $access_token, $is_sandbox = null ) {
|
62 |
+
$this->client = new SquareClient( [
|
63 |
+
'accessToken' => $access_token,
|
64 |
+
'environment' => $is_sandbox ? Environment::SANDBOX : Environment::PRODUCTION,
|
65 |
+
] );
|
|
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
|
68 |
|
76 |
*
|
77 |
* @param string[] $object_ids array of square catalog object IDs
|
78 |
* @return Responses\Catalog
|
79 |
+
* @throws \Exception
|
80 |
*/
|
81 |
public function batch_delete_catalog_objects( array $object_ids ) {
|
82 |
|
95 |
* @param string[] $object_ids array of square catalog object IDs
|
96 |
* @param bool $include_related_objects whether or not to include related objects in the response
|
97 |
* @return Responses\Catalog
|
98 |
+
* @throws \Exception
|
99 |
*/
|
100 |
public function batch_retrieve_catalog_objects( array $object_ids, $include_related_objects = false ) {
|
101 |
|
114 |
* @param string $idempotency_key a UUID for this request
|
115 |
* @param array $batches an array of batches to upsert
|
116 |
* @return Responses\Catalog
|
117 |
+
* @throws \Exception
|
118 |
*/
|
119 |
public function batch_upsert_catalog_objects( $idempotency_key, array $batches ) {
|
120 |
|
130 |
*
|
131 |
* @since 2.0.0
|
132 |
* @return Responses\Catalog
|
133 |
+
* @throws \Exception
|
134 |
*/
|
135 |
public function catalog_info() {
|
136 |
|
148 |
*
|
149 |
* @param string $object_id Square catalog object ID
|
150 |
* @return Responses\Catalog
|
151 |
+
* @throws \Exception
|
152 |
*/
|
153 |
public function delete_catalog_object( $object_id ) {
|
154 |
|
167 |
* @param string $cursor the cursor to list from
|
168 |
* @param string[] $types the item types to filter by
|
169 |
* @return Responses\Catalog
|
170 |
+
* @throws \Exception
|
171 |
*/
|
172 |
public function list_catalog( $cursor = '', $types = array() ) {
|
173 |
|
186 |
* @param string $object_id the Square catalog object ID
|
187 |
* @param bool $include_related_objects whether or not to include related objects (such as categories)
|
188 |
* @return Responses\Catalog
|
189 |
+
* @throws \Exception
|
190 |
*/
|
191 |
public function retrieve_catalog_object( $object_id, $include_related_objects = false ) {
|
192 |
|
204 |
*
|
205 |
* @param array $args see Catalog::set_search_catalog_objects_data() for list of args
|
206 |
* @return Responses\Catalog
|
207 |
+
* @throws \Exception
|
208 |
*/
|
209 |
public function search_catalog_objects( $args = array() ) {
|
210 |
|
224 |
* @param string[] $modifier_lists_to_enable (optional) modifier list IDs to enable
|
225 |
* @param string[] $modifier_lists_to_disable (optional) modifier list IDs to disable
|
226 |
* @return Responses\Catalog
|
227 |
+
* @throws \Exception
|
228 |
*/
|
229 |
public function update_item_modifier_lists( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
230 |
|
244 |
* @param string[] $taxes_to_enable (optional) tax IDs to enable
|
245 |
* @param string[] $taxes_to_disable (optional) tax IDs to disable
|
246 |
* @return Responses\Catalog
|
247 |
+
* @throws \Exception
|
248 |
*/
|
249 |
public function update_item_taxes( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
250 |
|
261 |
* @since 2.0.0
|
262 |
*
|
263 |
* @param string $idempotency_key UUID for this request
|
264 |
+
* @param \Square\Models\CatalogObject $object the object to upsert
|
265 |
* @return Responses\Catalog
|
266 |
+
* @throws \Exception
|
267 |
*/
|
268 |
public function upsert_catalog_object( $idempotency_key, $object ) {
|
269 |
|
285 |
* @param string $square_item_id
|
286 |
* @param string $caption optional image caption
|
287 |
* @return string
|
288 |
+
* @throws \Exception
|
289 |
*/
|
290 |
public function create_image( $image_path, $square_item_id = '', $caption = '' ) {
|
291 |
|
292 |
if ( ! is_readable( $image_path ) ) {
|
293 |
+
throw new \Exception( 'Image file is not readable' );
|
294 |
}
|
295 |
|
296 |
$image = file_get_contents( $image_path );
|
331 |
$body .= $image . "\r\n";
|
332 |
$body .= '--boundary--';
|
333 |
|
334 |
+
$url = $this->client->getBaseUri() . '/v2/catalog/images';
|
335 |
|
336 |
$response = wp_remote_post(
|
337 |
$url,
|
342 |
);
|
343 |
|
344 |
if ( is_wp_error( $response ) ) {
|
345 |
+
throw new \Exception( $response->get_error_message() );
|
346 |
}
|
347 |
|
348 |
$body = wp_remote_retrieve_body( $response );
|
349 |
$body = json_decode( $body, true );
|
350 |
|
351 |
if ( ! is_array( $body ) ) {
|
352 |
+
throw new \Exception( 'Response was malformed' );
|
353 |
}
|
354 |
|
355 |
if ( ! empty( $body['errors'] ) || empty( $body['image']['id'] ) ) {
|
360 |
$message = 'Unknown error';
|
361 |
}
|
362 |
|
363 |
+
throw new \Exception( $message );
|
364 |
}
|
365 |
|
366 |
return $body['image']['id'];
|
378 |
* @param string $square_id Square object ID
|
379 |
* @param int $amount amount of inventory to add
|
380 |
* @return Responses\Inventory
|
381 |
+
* @throws \Exception
|
382 |
*/
|
383 |
public function add_inventory_from_refund( $square_id, $amount ) {
|
384 |
|
395 |
* @param int $amount amount of inventory to add
|
396 |
* @param string $from_state the API state the inventory is coming from
|
397 |
* @return Responses\Inventory
|
398 |
+
* @throws \Exception
|
399 |
*/
|
400 |
public function add_inventory( $square_id, $amount, $from_state = 'NONE' ) {
|
401 |
|
411 |
* @param string $square_id Square object ID
|
412 |
* @param int $amount amount of inventory to remove
|
413 |
* @return Responses\Inventory
|
414 |
+
* @throws \Exception
|
415 |
*/
|
416 |
public function remove_inventory( $square_id, $amount ) {
|
417 |
|
429 |
* @param string $from_state the API state the inventory is coming from
|
430 |
* @param string $to_state the API state the inventory is changing to
|
431 |
* @return Responses\Inventory
|
432 |
+
* @throws \Exception
|
433 |
*/
|
434 |
protected function adjust_inventory( $square_id, $amount, $from_state, $to_state ) {
|
435 |
|
436 |
$date = new \DateTime();
|
437 |
|
438 |
+
$change = new \Square\Models\InventoryChange();
|
439 |
$change->setType( 'ADJUSTMENT' );
|
440 |
+
|
441 |
+
$inventory_adjustment = new \Square\Models\InventoryAdjustment();
|
442 |
+
$inventory_adjustment->setCatalogObjectId( $square_id );
|
443 |
+
$inventory_adjustment->setLocationId( $this->get_plugin()->get_settings_handler()->get_location_id() );
|
444 |
+
$inventory_adjustment->setQuantity( (string) absint( $amount ) );
|
445 |
+
$inventory_adjustment->setFromState( $from_state );
|
446 |
+
$inventory_adjustment->setToState( $to_state );
|
447 |
+
$inventory_adjustment->setOccurredAt( $date->format( DATE_ATOM ) );
|
448 |
+
|
449 |
+
$change->setAdjustment( $inventory_adjustment );
|
|
|
|
|
450 |
|
451 |
return $this->batch_change_inventory(
|
452 |
uniqid( '', false ),
|
463 |
* @since 2.0.0
|
464 |
*
|
465 |
* @param string $idempotency_key UUID for this request
|
466 |
+
* @param \Square\Models\InventoryChange[] $changes array of Inventory Changes
|
467 |
* @param bool $ignore_unchanged_counts whether the current physical count should be ignored if the quantity is unchanged since the last physical count
|
468 |
* @return Responses\Inventory
|
469 |
+
* @throws \Exception
|
470 |
*/
|
471 |
public function batch_change_inventory( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
472 |
|
485 |
* @param array $args see Requests\Inventory::set_batch_retrieve_inventory_changes_data() for accepted arguments
|
486 |
*
|
487 |
* @return Responses\Inventory
|
488 |
+
* @throws \Exception
|
489 |
*/
|
490 |
public function batch_retrieve_inventory_changes( array $args = array() ) {
|
491 |
|
504 |
* @param array $args see Requests\Inventory::set_batch_retrieve_inventory_counts_data() for accepted arguments
|
505 |
*
|
506 |
* @return Responses\Inventory
|
507 |
+
* @throws \Exception
|
508 |
*/
|
509 |
public function batch_retrieve_inventory_counts( array $args = array() ) {
|
510 |
|
523 |
* @param string $adjustment_id the InventoryAdjustment ID to retrieve
|
524 |
*
|
525 |
* @return Responses\Inventory
|
526 |
+
* @throws \Exception
|
527 |
*/
|
528 |
public function retrieve_inventory_adjustment( $adjustment_id ) {
|
529 |
|
542 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
543 |
*
|
544 |
* @return Responses\Inventory
|
545 |
+
* @throws \Exception
|
546 |
*/
|
547 |
public function retrieve_inventory_changes( $catalog_object_id ) {
|
548 |
|
560 |
*
|
561 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
562 |
* @return Responses\Inventory
|
563 |
+
* @throws \Exception
|
564 |
*/
|
565 |
public function retrieve_inventory_count( $catalog_object_id ) {
|
566 |
|
567 |
$request = $this->get_inventory_request();
|
568 |
+
$request->set_retrieve_inventory_count_data( $catalog_object_id, $this->get_plugin()->get_settings_handler()->get_location_id() );
|
569 |
|
570 |
return $this->perform_request( $request );
|
571 |
}
|
579 |
* @param string $physical_count_id the InventoryPhysicalCount ID to retrieve
|
580 |
*
|
581 |
* @return Responses\Inventory
|
582 |
+
* @throws \Exception
|
583 |
*/
|
584 |
public function retrieve_inventory_physical_count( $physical_count_id ) {
|
585 |
|
598 |
*
|
599 |
* @since 2.0.0
|
600 |
*
|
601 |
+
* @return \Square\Models\Location[]
|
602 |
+
* @throws \Exception
|
603 |
*/
|
604 |
public function get_locations() {
|
605 |
|
626 |
*
|
627 |
* @param string $cursor pagination cursor
|
628 |
* @return API\Response
|
629 |
+
* @throws \Exception
|
630 |
*/
|
631 |
public function get_customers( $cursor = '' ) {
|
632 |
|
649 |
* @since 2.0.0
|
650 |
*
|
651 |
* @return Requests\Catalog
|
652 |
+
* @throws \Exception
|
653 |
*/
|
654 |
protected function get_catalog_request() {
|
655 |
|
663 |
* @since 2.0.0
|
664 |
*
|
665 |
* @return Requests\Inventory
|
666 |
+
* @throws \Exception
|
667 |
*/
|
668 |
protected function get_inventory_request() {
|
669 |
|
678 |
*
|
679 |
* @param string $type desired request type
|
680 |
* @return Requests\Catalog|Requests\Inventory
|
681 |
+
* @throws \Exception
|
682 |
*/
|
683 |
protected function get_new_request( $type = '' ) {
|
684 |
|
695 |
break;
|
696 |
|
697 |
default:
|
698 |
+
throw new \Exception( 'Invalid request type.' );
|
699 |
}
|
700 |
|
701 |
$this->set_response_handler( $response_handler );
|
707 |
/**
|
708 |
* Performs an API request.
|
709 |
*
|
710 |
+
* @see Base::perform_request()
|
711 |
*
|
712 |
* @since 2.0.0
|
713 |
*
|
714 |
* @param API\Request $request request object
|
715 |
+
* @return API_Response
|
716 |
+
* @throws \Exception
|
717 |
*/
|
718 |
protected function perform_request( $request ) {
|
719 |
|
748 |
// parse & validate response
|
749 |
$response = $this->handle_response( $response );
|
750 |
|
751 |
+
} catch ( \Exception $e ) {
|
752 |
|
753 |
// alert other actors that a request has been made
|
754 |
$this->broadcast_request();
|
766 |
* @since 2.0.0
|
767 |
*
|
768 |
* @param array|\WP_Error $response response data
|
769 |
+
* @throws \Exception
|
770 |
+
* @return API_Response|object request class instance that implements API_Request
|
771 |
*/
|
772 |
protected function handle_response( $response ) {
|
|
|
|
|
|
|
|
|
773 |
// parse the response body and tie it to the request
|
774 |
$this->response = $this->get_parsed_response( $this->raw_response_body );
|
775 |
|
791 |
* @since 2.0.0
|
792 |
*
|
793 |
* @return bool
|
794 |
+
* @throws \Exception
|
795 |
*/
|
796 |
protected function do_post_parse_response_validation() {
|
797 |
|
830 |
}
|
831 |
|
832 |
// At this point we could not validate the response and assume a failed attempt.
|
833 |
+
throw new \Exception( implode( ' | ', $errors ) );
|
834 |
}
|
835 |
|
836 |
/**
|
841 |
* @param Object $square_api the square API class instance
|
842 |
* @param string $method the class method to call
|
843 |
* @param array $args the args to send with the method call
|
844 |
+
* @throws \Exception
|
845 |
*/
|
846 |
protected function do_square_request( $square_api, $method, $args ) {
|
847 |
|
848 |
if ( ! is_callable( array( $square_api, $method ) ) ) {
|
849 |
+
throw new \Exception( 'Invalid API method' );
|
850 |
}
|
851 |
|
852 |
+
// perform the request
|
853 |
+
$response = call_user_func_array( array( $square_api, $method ), $args );
|
854 |
|
855 |
+
if ( $response instanceof \Square\Http\ApiResponse ) {
|
856 |
+
$this->response_code = $response->getStatusCode();
|
857 |
+
$this->response_headers = $response->getHeaders();
|
858 |
|
859 |
+
if ( $response->isSuccess() ) {
|
860 |
+
$this->raw_response_body = $response->getResult();
|
|
|
|
|
861 |
} else {
|
862 |
+
$this->raw_response_body = $response->getErrors();
|
863 |
}
|
|
|
|
|
|
|
|
|
|
|
864 |
}
|
865 |
}
|
866 |
|
includes/API/Request.php
CHANGED
@@ -23,8 +23,8 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use SquareConnect\Configuration;
|
|
|
28 |
|
29 |
defined( 'ABSPATH' ) || exit;
|
30 |
|
@@ -33,7 +33,7 @@ defined( 'ABSPATH' ) || exit;
|
|
33 |
*
|
34 |
* @since 2.0.0
|
35 |
*/
|
36 |
-
class Request implements
|
37 |
|
38 |
|
39 |
/** @var Configuration the configuration object */
|
@@ -76,10 +76,7 @@ class Request implements Framework\SV_WC_API_Request {
|
|
76 |
* @return string
|
77 |
*/
|
78 |
public function get_square_api_method() {
|
79 |
-
|
80 |
-
$method = $this->square_api_method;
|
81 |
-
|
82 |
-
return $this->with_http_info ? $method . 'WithHttpInfo' : $method;
|
83 |
}
|
84 |
|
85 |
|
23 |
|
24 |
namespace WooCommerce\Square\API;
|
25 |
|
|
|
26 |
use SquareConnect\Configuration;
|
27 |
+
use \WooCommerce\Square\Framework\Api\API_Request;
|
28 |
|
29 |
defined( 'ABSPATH' ) || exit;
|
30 |
|
33 |
*
|
34 |
* @since 2.0.0
|
35 |
*/
|
36 |
+
class Request implements API_Request {
|
37 |
|
38 |
|
39 |
/** @var Configuration the configuration object */
|
76 |
* @return string
|
77 |
*/
|
78 |
public function get_square_api_method() {
|
79 |
+
return $this->square_api_method;
|
|
|
|
|
|
|
80 |
}
|
81 |
|
82 |
|
includes/API/Requests/Catalog.php
CHANGED
@@ -23,9 +23,6 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
-
use SquareConnect\Model as SquareModel;
|
28 |
-
use SquareConnect\Api\CatalogApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
defined( 'ABSPATH' ) || exit;
|
@@ -43,11 +40,10 @@ class Catalog extends Request {
|
|
43 |
*
|
44 |
* @since 2.0.0
|
45 |
*
|
46 |
-
* @param \
|
47 |
*/
|
48 |
public function __construct( $api_client ) {
|
49 |
-
|
50 |
-
$this->square_api = new CatalogApi( $api_client );
|
51 |
}
|
52 |
|
53 |
|
@@ -55,7 +51,7 @@ class Catalog extends Request {
|
|
55 |
* Sets the data for a batchDeleteCatalogObjects request.
|
56 |
*
|
57 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchdeletecatalogobjects
|
58 |
-
* @see \
|
59 |
*
|
60 |
* @since 2.0.0
|
61 |
*
|
@@ -64,7 +60,9 @@ class Catalog extends Request {
|
|
64 |
public function set_batch_delete_catalog_objects_data( array $object_ids ) {
|
65 |
|
66 |
$this->square_api_method = 'batchDeleteCatalogObjects';
|
67 |
-
$
|
|
|
|
|
68 |
}
|
69 |
|
70 |
|
@@ -72,7 +70,7 @@ class Catalog extends Request {
|
|
72 |
* Sets the data for a batchRetrieveCatalogObjects request.
|
73 |
*
|
74 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchretrievecatalogobjects
|
75 |
-
* @see \
|
76 |
*
|
77 |
* @since 2.0.0
|
78 |
*
|
@@ -82,14 +80,10 @@ class Catalog extends Request {
|
|
82 |
public function set_batch_retrieve_catalog_objects_data( array $object_ids, $include_related_objects = false ) {
|
83 |
|
84 |
$this->square_api_method = 'batchRetrieveCatalogObjects';
|
85 |
-
$
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
'include_related_objects' => (bool) $include_related_objects,
|
90 |
-
)
|
91 |
-
),
|
92 |
-
);
|
93 |
}
|
94 |
|
95 |
|
@@ -97,22 +91,20 @@ class Catalog extends Request {
|
|
97 |
* Sets the data for a batchUpsertCatalogObjects request.
|
98 |
*
|
99 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchupsertcatalogobjects
|
100 |
-
* @see \
|
101 |
*
|
102 |
* @since 2.0.0
|
103 |
*
|
104 |
* @param string $idempotency_key the UUID for this request
|
105 |
-
* @param
|
106 |
*/
|
107 |
public function set_batch_upsert_catalog_objects_data( $idempotency_key, array $batches ) {
|
108 |
|
109 |
$this->square_api_method = 'batchUpsertCatalogObjects';
|
110 |
$this->square_api_args = array(
|
111 |
-
new
|
112 |
-
|
113 |
-
|
114 |
-
'batches' => $batches,
|
115 |
-
)
|
116 |
),
|
117 |
);
|
118 |
}
|
@@ -122,7 +114,7 @@ class Catalog extends Request {
|
|
122 |
* Sets the data for a catalogInfo request.
|
123 |
*
|
124 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-cataloginfo
|
125 |
-
* @see \
|
126 |
*
|
127 |
* @since 2.0.0
|
128 |
*
|
@@ -139,7 +131,7 @@ class Catalog extends Request {
|
|
139 |
* Sets the data for a deleteCatalogObject request.
|
140 |
*
|
141 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-deletecatalogobject
|
142 |
-
* @see \
|
143 |
*
|
144 |
* @since 2.0.0
|
145 |
*
|
@@ -156,7 +148,7 @@ class Catalog extends Request {
|
|
156 |
* Sets the data for a listCatalog request.
|
157 |
*
|
158 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-listcatalog
|
159 |
-
* @see \
|
160 |
*
|
161 |
* @since 2.0.0
|
162 |
*
|
@@ -177,7 +169,7 @@ class Catalog extends Request {
|
|
177 |
* Sets the data for a retrieveCatalogObject request.
|
178 |
*
|
179 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-retrievecatalogobject
|
180 |
-
* @see \
|
181 |
*
|
182 |
* @since 2.0.0
|
183 |
*
|
@@ -195,7 +187,7 @@ class Catalog extends Request {
|
|
195 |
* Sets the data for a searchCatalogObjects request.
|
196 |
*
|
197 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-searchcatalogobjects
|
198 |
-
* @see \
|
199 |
*
|
200 |
* @since 2.0.0
|
201 |
*
|
@@ -221,8 +213,17 @@ class Catalog extends Request {
|
|
221 |
// apply defaults and remove any keys that aren't recognized
|
222 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
$this->square_api_method = 'searchCatalogObjects';
|
225 |
-
$this->square_api_args = array(
|
226 |
}
|
227 |
|
228 |
|
@@ -230,7 +231,7 @@ class Catalog extends Request {
|
|
230 |
* Sets the data for a updateItemModifierLists request.
|
231 |
*
|
232 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-updateitemmodifierlists
|
233 |
-
* @see \
|
234 |
*
|
235 |
* @since 2.0.0
|
236 |
*
|
@@ -241,15 +242,11 @@ class Catalog extends Request {
|
|
241 |
public function set_update_item_modifier_lists_data( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
242 |
|
243 |
$this->square_api_method = 'updateItemModifierLists';
|
244 |
-
$
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
'modifier_lists_to_disable' => $modifier_lists_to_disable,
|
250 |
-
)
|
251 |
-
),
|
252 |
-
);
|
253 |
}
|
254 |
|
255 |
|
@@ -257,7 +254,7 @@ class Catalog extends Request {
|
|
257 |
* Sets the data for an updateItemTaxes request.
|
258 |
*
|
259 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-updateitemtaxes
|
260 |
-
* @see \
|
261 |
*
|
262 |
* @since 2.0.0
|
263 |
*
|
@@ -268,15 +265,10 @@ class Catalog extends Request {
|
|
268 |
public function set_update_item_taxes_data( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
269 |
|
270 |
$this->square_api_method = 'updateItemTaxes';
|
271 |
-
$
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
'taxes_to_enable' => $taxes_to_enable,
|
276 |
-
'taxes_to_disable' => $taxes_to_disable,
|
277 |
-
)
|
278 |
-
),
|
279 |
-
);
|
280 |
}
|
281 |
|
282 |
|
@@ -284,22 +276,20 @@ class Catalog extends Request {
|
|
284 |
* Sets the data for an upsertCatalogObject request.
|
285 |
*
|
286 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-upsertcatalogobject
|
287 |
-
* @see \
|
288 |
*
|
289 |
* @since 2.0.0
|
290 |
*
|
291 |
* @param string $idempotency_key a UUID for this request
|
292 |
-
* @param
|
293 |
*/
|
294 |
public function set_upsert_catalog_object_data( $idempotency_key, $object ) {
|
295 |
|
296 |
$this->square_api_method = 'upsertCatalogObject';
|
297 |
$this->square_api_args = array(
|
298 |
-
new
|
299 |
-
|
300 |
-
|
301 |
-
'object' => $object,
|
302 |
-
)
|
303 |
),
|
304 |
);
|
305 |
}
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
|
|
|
|
|
|
26 |
use WooCommerce\Square\API\Request;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
40 |
*
|
41 |
* @since 2.0.0
|
42 |
*
|
43 |
+
* @param \Square\SquareClient $api_client the API client
|
44 |
*/
|
45 |
public function __construct( $api_client ) {
|
46 |
+
$this->square_api = $api_client->getCatalogApi();
|
|
|
47 |
}
|
48 |
|
49 |
|
51 |
* Sets the data for a batchDeleteCatalogObjects request.
|
52 |
*
|
53 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchdeletecatalogobjects
|
54 |
+
* @see \Square\Apis\CatalogApi::batchDeleteCatalogObjects()
|
55 |
*
|
56 |
* @since 2.0.0
|
57 |
*
|
60 |
public function set_batch_delete_catalog_objects_data( array $object_ids ) {
|
61 |
|
62 |
$this->square_api_method = 'batchDeleteCatalogObjects';
|
63 |
+
$body = new \Square\Models\BatchDeleteCatalogObjectsRequest();
|
64 |
+
$body->setObjectIds( $object_ids );
|
65 |
+
$this->square_api_args = array( $body );
|
66 |
}
|
67 |
|
68 |
|
70 |
* Sets the data for a batchRetrieveCatalogObjects request.
|
71 |
*
|
72 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchretrievecatalogobjects
|
73 |
+
* @see \Square\Apis\CatalogApi::batchRetrieveCatalogObjects()
|
74 |
*
|
75 |
* @since 2.0.0
|
76 |
*
|
80 |
public function set_batch_retrieve_catalog_objects_data( array $object_ids, $include_related_objects = false ) {
|
81 |
|
82 |
$this->square_api_method = 'batchRetrieveCatalogObjects';
|
83 |
+
$body = new \Square\Models\BatchRetrieveCatalogObjectsRequest( $object_ids );
|
84 |
+
$body->setIncludeRelatedObjects( (bool) $include_related_objects );
|
85 |
+
|
86 |
+
$this->square_api_args = array( $body );
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
|
91 |
* Sets the data for a batchUpsertCatalogObjects request.
|
92 |
*
|
93 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-batchupsertcatalogobjects
|
94 |
+
* @see \Square\Apis\CatalogApi::batchUpsertCatalogObjects()
|
95 |
*
|
96 |
* @since 2.0.0
|
97 |
*
|
98 |
* @param string $idempotency_key the UUID for this request
|
99 |
+
* @param \Square\Models\CatalogObjectBatch[] $batches array of catalog object batches
|
100 |
*/
|
101 |
public function set_batch_upsert_catalog_objects_data( $idempotency_key, array $batches ) {
|
102 |
|
103 |
$this->square_api_method = 'batchUpsertCatalogObjects';
|
104 |
$this->square_api_args = array(
|
105 |
+
new \Square\Models\BatchUpsertCatalogObjectsRequest(
|
106 |
+
$idempotency_key,
|
107 |
+
$batches
|
|
|
|
|
108 |
),
|
109 |
);
|
110 |
}
|
114 |
* Sets the data for a catalogInfo request.
|
115 |
*
|
116 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-cataloginfo
|
117 |
+
* @see \Square\Apis\CatalogApi::catalogInfo()
|
118 |
*
|
119 |
* @since 2.0.0
|
120 |
*
|
131 |
* Sets the data for a deleteCatalogObject request.
|
132 |
*
|
133 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-deletecatalogobject
|
134 |
+
* @see \Square\Apis\CatalogApi::deleteCatalogObject()
|
135 |
*
|
136 |
* @since 2.0.0
|
137 |
*
|
148 |
* Sets the data for a listCatalog request.
|
149 |
*
|
150 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-listcatalog
|
151 |
+
* @see \Square\Apis\CatalogApi::listCatalog()
|
152 |
*
|
153 |
* @since 2.0.0
|
154 |
*
|
169 |
* Sets the data for a retrieveCatalogObject request.
|
170 |
*
|
171 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-retrievecatalogobject
|
172 |
+
* @see \Square\Apis\CatalogApi::retrieveCatalogObject()
|
173 |
*
|
174 |
* @since 2.0.0
|
175 |
*
|
187 |
* Sets the data for a searchCatalogObjects request.
|
188 |
*
|
189 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-searchcatalogobjects
|
190 |
+
* @see \Square\Apis\CatalogApi::searchCatalogObjects()
|
191 |
*
|
192 |
* @since 2.0.0
|
193 |
*
|
213 |
// apply defaults and remove any keys that aren't recognized
|
214 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
215 |
|
216 |
+
$body = new \Square\Models\SearchCatalogObjectsRequest();
|
217 |
+
$body->setCursor( $args['cursor'] );
|
218 |
+
$body->setObjectTypes( $args['object_types'] );
|
219 |
+
$body->setIncludeDeletedObjects( $args['include_deleted_objects'] );
|
220 |
+
$body->setIncludeRelatedObjects( $args['include_related_objects'] );
|
221 |
+
$body->setBeginTime( $args['begin_time'] );
|
222 |
+
$body->setQuery( $args['query'] );
|
223 |
+
$body->setLimit( $args['limit'] );
|
224 |
+
|
225 |
$this->square_api_method = 'searchCatalogObjects';
|
226 |
+
$this->square_api_args = array( $body );
|
227 |
}
|
228 |
|
229 |
|
231 |
* Sets the data for a updateItemModifierLists request.
|
232 |
*
|
233 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-updateitemmodifierlists
|
234 |
+
* @see \Square\Apis\CatalogApi::updateItemModifierLists()
|
235 |
*
|
236 |
* @since 2.0.0
|
237 |
*
|
242 |
public function set_update_item_modifier_lists_data( array $item_ids, array $modifier_lists_to_enable = array(), array $modifier_lists_to_disable = array() ) {
|
243 |
|
244 |
$this->square_api_method = 'updateItemModifierLists';
|
245 |
+
$body = new \Square\Models\UpdateItemModifierListsRequest( $item_ids );
|
246 |
+
$body->setModifierListsToEnable( $modifier_lists_to_enable );
|
247 |
+
$body->setModifierListsToDisable( $modifier_lists_to_disable );
|
248 |
+
|
249 |
+
$this->square_api_args = array( $body );
|
|
|
|
|
|
|
|
|
250 |
}
|
251 |
|
252 |
|
254 |
* Sets the data for an updateItemTaxes request.
|
255 |
*
|
256 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-updateitemtaxes
|
257 |
+
* @see \Square\Apis\CatalogApi::updateItemTaxes()
|
258 |
*
|
259 |
* @since 2.0.0
|
260 |
*
|
265 |
public function set_update_item_taxes_data( array $item_ids, array $taxes_to_enable = array(), array $taxes_to_disable = array() ) {
|
266 |
|
267 |
$this->square_api_method = 'updateItemTaxes';
|
268 |
+
$body = new \Square\Models\UpdateItemTaxesRequest( $item_ids );
|
269 |
+
$body->setTaxesToEnable( $taxes_to_enable );
|
270 |
+
$body->setTaxesToDisable( $taxes_to_disable );
|
271 |
+
$this->square_api_args = array( $body );
|
|
|
|
|
|
|
|
|
|
|
272 |
}
|
273 |
|
274 |
|
276 |
* Sets the data for an upsertCatalogObject request.
|
277 |
*
|
278 |
* @see https://docs.connect.squareup.com/api/connect/v2#endpoint-catalog-upsertcatalogobject
|
279 |
+
* @see \Square\Apis\CatalogApi::upsertCatalogObject()
|
280 |
*
|
281 |
* @since 2.0.0
|
282 |
*
|
283 |
* @param string $idempotency_key a UUID for this request
|
284 |
+
* @param \Square\Models\CatalogObject $object the object to update
|
285 |
*/
|
286 |
public function set_upsert_catalog_object_data( $idempotency_key, $object ) {
|
287 |
|
288 |
$this->square_api_method = 'upsertCatalogObject';
|
289 |
$this->square_api_args = array(
|
290 |
+
new \Square\Models\UpsertCatalogObjectRequest(
|
291 |
+
$idempotency_key,
|
292 |
+
$object
|
|
|
|
|
293 |
),
|
294 |
);
|
295 |
}
|
includes/API/Requests/Customers.php
CHANGED
@@ -25,7 +25,6 @@ namespace WooCommerce\Square\API\Requests;
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SquareConnect\Api\CustomersApi;
|
29 |
use WooCommerce\Square\API;
|
30 |
|
31 |
/**
|
@@ -41,11 +40,10 @@ class Customers extends API\Request {
|
|
41 |
*
|
42 |
* @since 2.0.0
|
43 |
*
|
44 |
-
* @param \
|
45 |
*/
|
46 |
public function __construct( $api_client ) {
|
47 |
-
|
48 |
-
$this->square_api = new CustomersApi( $api_client );
|
49 |
}
|
50 |
|
51 |
|
@@ -76,7 +74,7 @@ class Customers extends API\Request {
|
|
76 |
$this->square_api_method = 'listCustomers';
|
77 |
|
78 |
if ( $cursor ) {
|
79 |
-
$this->square_api_args = array(
|
80 |
}
|
81 |
}
|
82 |
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
|
|
28 |
use WooCommerce\Square\API;
|
29 |
|
30 |
/**
|
40 |
*
|
41 |
* @since 2.0.0
|
42 |
*
|
43 |
+
* @param \Square\SquareClient $api_client the API client
|
44 |
*/
|
45 |
public function __construct( $api_client ) {
|
46 |
+
$this->square_api = $api_client->getCustomersApi();
|
|
|
47 |
}
|
48 |
|
49 |
|
74 |
$this->square_api_method = 'listCustomers';
|
75 |
|
76 |
if ( $cursor ) {
|
77 |
+
$this->square_api_args = array( $cursor );
|
78 |
}
|
79 |
}
|
80 |
|
includes/API/Requests/Inventory.php
CHANGED
@@ -23,9 +23,6 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
-
use SquareConnect\Model as SquareModel;
|
28 |
-
use SquareConnect\Api\InventoryApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
defined( 'ABSPATH' ) || exit;
|
@@ -43,11 +40,10 @@ class Inventory extends Request {
|
|
43 |
*
|
44 |
* @since 2.0.0
|
45 |
*
|
46 |
-
* @param \
|
47 |
*/
|
48 |
public function __construct( $api_client ) {
|
49 |
-
|
50 |
-
$this->square_api = new InventoryApi( $api_client );
|
51 |
}
|
52 |
|
53 |
|
@@ -60,21 +56,16 @@ class Inventory extends Request {
|
|
60 |
* @since 2.0.0
|
61 |
*
|
62 |
* @param string $idempotency_key a UUID for this request
|
63 |
-
* @param
|
64 |
* @param bool $ignore_unchanged_counts whether the current physical count should be ignored if the quantity is unchanged since the last physical count
|
65 |
*/
|
66 |
public function set_batch_change_inventory_data( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
67 |
|
|
|
|
|
|
|
68 |
$this->square_api_method = 'batchChangeInventory';
|
69 |
-
$this->square_api_args = array(
|
70 |
-
new SquareModel\BatchChangeInventoryRequest(
|
71 |
-
array(
|
72 |
-
'idempotency_key' => $idempotency_key,
|
73 |
-
'changes' => $changes,
|
74 |
-
'ignore_unchanged_counts' => (bool) $ignore_unchanged_counts,
|
75 |
-
)
|
76 |
-
),
|
77 |
-
);
|
78 |
}
|
79 |
|
80 |
|
@@ -109,9 +100,17 @@ class Inventory extends Request {
|
|
109 |
|
110 |
// apply defaults and remove any keys that aren't recognized
|
111 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
$this->square_api_method = 'batchRetrieveInventoryChanges';
|
114 |
-
$this->square_api_args = array(
|
115 |
}
|
116 |
|
117 |
|
@@ -140,9 +139,13 @@ class Inventory extends Request {
|
|
140 |
|
141 |
// apply defaults and remove any keys that aren't recognized
|
142 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
143 |
-
|
|
|
|
|
|
|
|
|
144 |
$this->square_api_method = 'batchRetrieveInventoryCounts';
|
145 |
-
$this->square_api_args = array(
|
146 |
}
|
147 |
|
148 |
|
@@ -175,8 +178,15 @@ class Inventory extends Request {
|
|
175 |
*/
|
176 |
public function set_retrieve_inventory_changes_data( $catalog_object_id ) {
|
177 |
|
178 |
-
|
179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
}
|
181 |
|
182 |
|
@@ -189,9 +199,9 @@ class Inventory extends Request {
|
|
189 |
* @since 2.0.0
|
190 |
*
|
191 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
192 |
-
* @param string
|
193 |
*/
|
194 |
-
public function set_retrieve_inventory_count_data( $catalog_object_id,
|
195 |
|
196 |
$this->square_api_method = 'retrieveInventoryCount';
|
197 |
$this->square_api_args = array( $catalog_object_id, $location_ids );
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
|
|
|
|
|
|
|
26 |
use WooCommerce\Square\API\Request;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
40 |
*
|
41 |
* @since 2.0.0
|
42 |
*
|
43 |
+
* @param \Square\SquareClient $api_client the API client
|
44 |
*/
|
45 |
public function __construct( $api_client ) {
|
46 |
+
$this->square_api = $api_client->getInventoryApi();
|
|
|
47 |
}
|
48 |
|
49 |
|
56 |
* @since 2.0.0
|
57 |
*
|
58 |
* @param string $idempotency_key a UUID for this request
|
59 |
+
* @param \Square\Models\InventoryChange[] $changes array of inventory changes to be made
|
60 |
* @param bool $ignore_unchanged_counts whether the current physical count should be ignored if the quantity is unchanged since the last physical count
|
61 |
*/
|
62 |
public function set_batch_change_inventory_data( $idempotency_key, $changes, $ignore_unchanged_counts = true ) {
|
63 |
|
64 |
+
$body = new \Square\Models\BatchChangeInventoryRequest( $idempotency_key );
|
65 |
+
$body->setChanges( $changes );
|
66 |
+
$body->setIgnoreUnchangedCounts( (bool) $ignore_unchanged_counts );
|
67 |
$this->square_api_method = 'batchChangeInventory';
|
68 |
+
$this->square_api_args = array( $body );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
|
71 |
|
100 |
|
101 |
// apply defaults and remove any keys that aren't recognized
|
102 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
103 |
+
$body = new \Square\Models\BatchRetrieveInventoryChangesRequest();
|
104 |
+
$body->setCatalogObjectIds( $args['catalog_object_ids'] );
|
105 |
+
$body->setLocationIds( $args['location_ids'] );
|
106 |
+
$body->setTypes( $args['types'] );
|
107 |
+
$body->setStates( $args['states'] );
|
108 |
+
$body->setUpdatedAfter( $args['updated_after'] );
|
109 |
+
$body->setUpdatedBefore( $args['updated_before'] );
|
110 |
+
$body->setCursor( $args['cursor'] );
|
111 |
|
112 |
$this->square_api_method = 'batchRetrieveInventoryChanges';
|
113 |
+
$this->square_api_args = array( $body );
|
114 |
}
|
115 |
|
116 |
|
139 |
|
140 |
// apply defaults and remove any keys that aren't recognized
|
141 |
$args = array_intersect_key( wp_parse_args( $args, $defaults ), $defaults );
|
142 |
+
$body = new \Square\Models\BatchRetrieveInventoryCountsRequest();
|
143 |
+
$body->setCatalogObjectIds( $args['catalog_object_ids'] );
|
144 |
+
$body->setLocationIds( $args['location_ids'] );
|
145 |
+
$body->setUpdatedAfter( $args['updated_after'] );
|
146 |
+
$body->setCursor( $args['cursor'] );
|
147 |
$this->square_api_method = 'batchRetrieveInventoryCounts';
|
148 |
+
$this->square_api_args = array( $body );
|
149 |
}
|
150 |
|
151 |
|
178 |
*/
|
179 |
public function set_retrieve_inventory_changes_data( $catalog_object_id ) {
|
180 |
|
181 |
+
/**
|
182 |
+
* `retrieveInventoryChanges` is deprecated.
|
183 |
+
* Using `batchRetrieveInventoryChanges` instead.
|
184 |
+
*/
|
185 |
+
$this->square_api_method = 'batchRetrieveInventoryChanges';
|
186 |
+
$body = new \Square\Models\BatchRetrieveInventoryChangesRequest();
|
187 |
+
$body->setCatalogObjectIds( [ $catalog_object_id ] );
|
188 |
+
|
189 |
+
$this->square_api_args = array( $body );
|
190 |
}
|
191 |
|
192 |
|
199 |
* @since 2.0.0
|
200 |
*
|
201 |
* @param string $catalog_object_id the CatalogObject ID to retrieve
|
202 |
+
* @param string $location_ids location IDs
|
203 |
*/
|
204 |
+
public function set_retrieve_inventory_count_data( $catalog_object_id, string $location_ids = '' ) {
|
205 |
|
206 |
$this->square_api_method = 'retrieveInventoryCount';
|
207 |
$this->square_api_args = array( $catalog_object_id, $location_ids );
|
includes/API/Requests/Locations.php
CHANGED
@@ -22,10 +22,6 @@
|
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
25 |
-
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
-
use SquareConnect\Model as SquareModel;
|
28 |
-
use SquareConnect\Api\LocationsApi;
|
29 |
use WooCommerce\Square\API\Request;
|
30 |
|
31 |
defined( 'ABSPATH' ) || exit;
|
@@ -43,11 +39,10 @@ class Locations extends Request {
|
|
43 |
*
|
44 |
* @since 2.0.0
|
45 |
*
|
46 |
-
* @param \
|
47 |
*/
|
48 |
public function __construct( $api_client ) {
|
49 |
-
|
50 |
-
$this->square_api = new LocationsApi( $api_client );
|
51 |
}
|
52 |
|
53 |
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API\Requests;
|
|
|
|
|
|
|
|
|
25 |
use WooCommerce\Square\API\Request;
|
26 |
|
27 |
defined( 'ABSPATH' ) || exit;
|
39 |
*
|
40 |
* @since 2.0.0
|
41 |
*
|
42 |
+
* @param \Square\SquareClient $api_client the API client
|
43 |
*/
|
44 |
public function __construct( $api_client ) {
|
45 |
+
$this->square_api = $api_client->getLocationsApi();
|
|
|
46 |
}
|
47 |
|
48 |
|
includes/API/Response.php
CHANGED
@@ -22,8 +22,7 @@
|
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API;
|
25 |
-
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
29 |
|
@@ -32,13 +31,10 @@ defined( 'ABSPATH' ) || exit;
|
|
32 |
*
|
33 |
* @since 2.0.0
|
34 |
*/
|
35 |
-
class Response implements
|
36 |
-
|
37 |
-
|
38 |
/** @var mixed raw response data */
|
39 |
protected $raw_response_data;
|
40 |
|
41 |
-
|
42 |
/**
|
43 |
* Constructs the response object.
|
44 |
*
|
@@ -73,8 +69,13 @@ class Response implements Framework\SV_WC_API_Response {
|
|
73 |
* @return \stdClass[]
|
74 |
*/
|
75 |
public function get_errors() {
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
-
return
|
78 |
}
|
79 |
|
80 |
|
@@ -95,13 +96,12 @@ class Response implements Framework\SV_WC_API_Response {
|
|
95 |
* Determines if the API response contains a particular error code.
|
96 |
*
|
97 |
* @since 2.1.6
|
98 |
-
*
|
99 |
* @return bool
|
100 |
*/
|
101 |
public function has_error_code( $error_code ) {
|
102 |
-
|
103 |
foreach ( $this->get_errors() as $error ) {
|
104 |
-
if ( $error_code === $error->
|
105 |
return true;
|
106 |
}
|
107 |
}
|
@@ -117,8 +117,15 @@ class Response implements Framework\SV_WC_API_Response {
|
|
117 |
* @return string
|
118 |
*/
|
119 |
public function to_string() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
-
return
|
122 |
}
|
123 |
|
124 |
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API;
|
25 |
+
use \WooCommerce\Square\Framework\Api\API_Response;
|
|
|
26 |
|
27 |
defined( 'ABSPATH' ) || exit;
|
28 |
|
31 |
*
|
32 |
* @since 2.0.0
|
33 |
*/
|
34 |
+
class Response implements API_Response {
|
|
|
|
|
35 |
/** @var mixed raw response data */
|
36 |
protected $raw_response_data;
|
37 |
|
|
|
38 |
/**
|
39 |
* Constructs the response object.
|
40 |
*
|
69 |
* @return \stdClass[]
|
70 |
*/
|
71 |
public function get_errors() {
|
72 |
+
if ( is_array( $this->raw_response_data ) && count( $this->raw_response_data ) > 0 ) {
|
73 |
+
if ( $this->raw_response_data[0] instanceof \Square\Models\Error ) {
|
74 |
+
return $this->raw_response_data;
|
75 |
+
}
|
76 |
+
}
|
77 |
|
78 |
+
return array();
|
79 |
}
|
80 |
|
81 |
|
96 |
* Determines if the API response contains a particular error code.
|
97 |
*
|
98 |
* @since 2.1.6
|
99 |
+
* @param $error \Square\Models\Error
|
100 |
* @return bool
|
101 |
*/
|
102 |
public function has_error_code( $error_code ) {
|
|
|
103 |
foreach ( $this->get_errors() as $error ) {
|
104 |
+
if ( $error_code === $error->getCode() ) {
|
105 |
return true;
|
106 |
}
|
107 |
}
|
117 |
* @return string
|
118 |
*/
|
119 |
public function to_string() {
|
120 |
+
$response_data = $this->get_data();
|
121 |
+
|
122 |
+
if ( is_callable( array( $response_data, '__toString' ) ) ) {
|
123 |
+
return $this->get_data();
|
124 |
+
} else if ( is_callable( array( $response_data, 'jsonSerialize' ) ) ) {
|
125 |
+
return wp_json_encode( $response_data, JSON_PRETTY_PRINT );
|
126 |
+
}
|
127 |
|
128 |
+
return '';
|
129 |
}
|
130 |
|
131 |
|
includes/API/Responses/Catalog.php
CHANGED
@@ -23,7 +23,6 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
use WooCommerce\Square\API\Response;
|
28 |
|
29 |
defined( 'ABSPATH' ) || exit;
|
@@ -33,7 +32,7 @@ defined( 'ABSPATH' ) || exit;
|
|
33 |
*
|
34 |
* @since 2.0.0
|
35 |
*
|
36 |
-
* @method \
|
37 |
*/
|
38 |
class Catalog extends Response {
|
39 |
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
|
|
26 |
use WooCommerce\Square\API\Response;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
32 |
*
|
33 |
* @since 2.0.0
|
34 |
*
|
35 |
+
* @method \Square\Models\ListCatalogResponse|\Square\Models\BatchUpsertCatalogObjectsResponse|\Square\Models\SearchCatalogObjectsResponse|\Square\Models\RetrieveCatalogObjectResponse|\Square\Models\CatalogInfoResponse get_data()
|
36 |
*/
|
37 |
class Catalog extends Response {
|
38 |
|
includes/API/Responses/Connection_Refresh_Response.php
CHANGED
@@ -22,11 +22,10 @@
|
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
-
|
30 |
/**
|
31 |
* The connection refresh response class.
|
32 |
*
|
@@ -34,8 +33,7 @@ use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
|
34 |
*
|
35 |
* @since 2.0.0
|
36 |
*/
|
37 |
-
class Connection_Refresh_Response extends
|
38 |
-
|
39 |
|
40 |
/**
|
41 |
* Gets the access token, if any.
|
@@ -95,6 +93,4 @@ class Connection_Refresh_Response extends Framework\SV_WC_API_JSON_Response {
|
|
95 |
|
96 |
return ! empty( $this->response_data->error );
|
97 |
}
|
98 |
-
|
99 |
-
|
100 |
}
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
+
use WooCommerce\Square\Framework\Api\API_JSON_Response;
|
26 |
|
27 |
defined( 'ABSPATH' ) || exit;
|
28 |
|
|
|
|
|
29 |
/**
|
30 |
* The connection refresh response class.
|
31 |
*
|
33 |
*
|
34 |
* @since 2.0.0
|
35 |
*/
|
36 |
+
class Connection_Refresh_Response extends API_JSON_Response {
|
|
|
37 |
|
38 |
/**
|
39 |
* Gets the access token, if any.
|
93 |
|
94 |
return ! empty( $this->response_data->error );
|
95 |
}
|
|
|
|
|
96 |
}
|
includes/API/Responses/Inventory.php
CHANGED
@@ -23,8 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
-
use
|
27 |
-
use SquareConnect\Model\BatchRetrieveInventoryCountsResponse;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
defined( 'ABSPATH' ) || exit;
|
@@ -42,7 +41,7 @@ class Inventory extends Response {
|
|
42 |
*
|
43 |
* @since 2.0.0
|
44 |
*
|
45 |
-
* @return \
|
46 |
*/
|
47 |
public function get_counts() {
|
48 |
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
+
use Square\Models\BatchRetrieveInventoryCountsResponse;
|
|
|
27 |
use WooCommerce\Square\API\Response;
|
28 |
|
29 |
defined( 'ABSPATH' ) || exit;
|
41 |
*
|
42 |
* @since 2.0.0
|
43 |
*
|
44 |
+
* @return \Square\Models\InventoryCount[] array of inventory count objects
|
45 |
*/
|
46 |
public function get_counts() {
|
47 |
|
includes/API/Responses/Locations.php
CHANGED
@@ -23,8 +23,6 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
-
use SquareConnect\Model as SquareModel;
|
28 |
use WooCommerce\Square\API\Response;
|
29 |
|
30 |
defined( 'ABSPATH' ) || exit;
|
@@ -34,7 +32,7 @@ defined( 'ABSPATH' ) || exit;
|
|
34 |
*
|
35 |
* @since 2.0.0
|
36 |
*
|
37 |
-
* @method
|
38 |
*/
|
39 |
class Locations extends Response {
|
40 |
|
@@ -44,7 +42,7 @@ class Locations extends Response {
|
|
44 |
*
|
45 |
* @since 2.0.0
|
46 |
*
|
47 |
-
* @return
|
48 |
*/
|
49 |
public function get_locations() {
|
50 |
|
23 |
|
24 |
namespace WooCommerce\Square\API\Responses;
|
25 |
|
|
|
|
|
26 |
use WooCommerce\Square\API\Response;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
32 |
*
|
33 |
* @since 2.0.0
|
34 |
*
|
35 |
+
* @method \Square\Models\ListLocationsResponse get_data()
|
36 |
*/
|
37 |
class Locations extends Response {
|
38 |
|
42 |
*
|
43 |
* @since 2.0.0
|
44 |
*
|
45 |
+
* @return \Square\Models\Location[]
|
46 |
*/
|
47 |
public function get_locations() {
|
48 |
|
includes/Admin.php
CHANGED
@@ -183,7 +183,6 @@ class Admin {
|
|
183 |
'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
|
184 |
'is_sandbox' => $this->get_plugin()->get_settings_handler()->is_sandbox(),
|
185 |
'existing_sync_job_id' => $existing_sync_id,
|
186 |
-
'sync_in_background' => $this->get_plugin()->get_sync_handler()->should_sync_in_background(),
|
187 |
'import_products_from_square' => wp_create_nonce( 'import-products-from-square' ),
|
188 |
'sync_products_with_square' => wp_create_nonce( 'sync-products-with-square' ),
|
189 |
'get_sync_with_square_status_nonce' => wp_create_nonce( 'get-sync-with-square-status' ),
|
183 |
'is_inventory_sync_enabled' => $this->get_plugin()->get_settings_handler()->is_inventory_sync_enabled(),
|
184 |
'is_sandbox' => $this->get_plugin()->get_settings_handler()->is_sandbox(),
|
185 |
'existing_sync_job_id' => $existing_sync_id,
|
|
|
186 |
'import_products_from_square' => wp_create_nonce( 'import-products-from-square' ),
|
187 |
'sync_products_with_square' => wp_create_nonce( 'sync-products-with-square' ),
|
188 |
'get_sync_with_square_status_nonce' => wp_create_nonce( 'get-sync-with-square-status' ),
|
includes/Admin/Privacy.php
CHANGED
@@ -25,8 +25,6 @@ namespace WooCommerce\Square\Admin;
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
-
|
30 |
/**
|
31 |
* Privacy admin handler.
|
32 |
*
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
|
|
|
|
28 |
/**
|
29 |
* Privacy admin handler.
|
30 |
*
|
includes/Admin/Settings_Page.php
CHANGED
@@ -25,7 +25,6 @@ namespace WooCommerce\Square\Admin;
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square;
|
30 |
|
31 |
/**
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
|
|
28 |
use WooCommerce\Square;
|
29 |
|
30 |
/**
|
includes/Admin/Sync_Page.php
CHANGED
@@ -25,7 +25,6 @@ namespace WooCommerce\Square\Admin;
|
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
29 |
use WooCommerce\Square\Handlers\Product;
|
30 |
use WooCommerce\Square\Sync\Records;
|
31 |
|
25 |
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
|
|
28 |
use WooCommerce\Square\Handlers\Product;
|
29 |
use WooCommerce\Square\Sync\Records;
|
30 |
|
includes/Emails/Access_Token_Email.php
CHANGED
@@ -23,8 +23,6 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Emails;
|
25 |
|
26 |
-
use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
|
27 |
-
|
28 |
defined( 'ABSPATH' ) || exit;
|
29 |
|
30 |
/**
|
23 |
|
24 |
namespace WooCommerce\Square\Emails;
|
25 |
|
|
|
|
|
26 |
defined( 'ABSPATH' ) || exit;
|
27 |
|
28 |
/**
|
includes/Emails/Base_Email.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
|
24 |
namespace WooCommerce\Square\Emails;
|
25 |
|
26 |
-
use
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
29 |
|
@@ -106,7 +106,7 @@ class Base_Email extends \WC_Email {
|
|
106 |
}
|
107 |
|
108 |
// add a recipient field
|
109 |
-
$form_fields =
|
110 |
$form_fields,
|
111 |
isset( $form_fields['enabled'] ) ? 'enabled' : key( $form_fields ),
|
112 |
array(
|
23 |
|
24 |
namespace WooCommerce\Square\Emails;
|
25 |
|
26 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
29 |
|
106 |
}
|
107 |
|
108 |
// add a recipient field
|
109 |
+
$form_fields = Square_Helper::array_insert_after(
|
110 |
$form_fields,
|
111 |
isset( $form_fields['enabled'] ) ? 'enabled' : key( $form_fields ),
|
112 |
array(
|
includes/Emails/Sync_Completed.php
CHANGED
@@ -1,29 +1,17 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
-
*
|
6 |
-
*
|
7 |
-
* It is also available through the world-wide-web at this URL:
|
8 |
-
* http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
-
* If you did not receive a copy of the license and are unable to
|
10 |
-
* obtain it through the world-wide-web, please send an email
|
11 |
-
* to license@woocommerce.com so we can send you a copy immediately.
|
12 |
*
|
13 |
-
*
|
14 |
-
*
|
15 |
-
* Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
|
16 |
-
* versions in the future. If you wish to customize WooCommerce Square for your
|
17 |
-
* needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
|
18 |
-
*
|
19 |
-
* @author WooCommerce
|
20 |
-
* @copyright Copyright: (c) 2019, Automattic, Inc.
|
21 |
-
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
22 |
*/
|
23 |
|
24 |
namespace WooCommerce\Square\Emails;
|
25 |
|
26 |
-
use
|
27 |
|
28 |
defined( 'ABSPATH' ) || exit;
|
29 |
|
@@ -226,7 +214,7 @@ class Sync_Completed extends Base_Email {
|
|
226 |
);
|
227 |
|
228 |
// TODO update handling when WooCommerce 3.2 is the minimum required version {FN 2019-05-03}
|
229 |
-
if (
|
230 |
foreach ( $email_merge_tags as $find => $replace ) {
|
231 |
$this->placeholders[ '{' . $find . '}' ] = $replace;
|
232 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sync Completed Email class
|
4 |
*
|
5 |
+
* Contains class that adds functionality to send out emails
|
6 |
+
* whenever sync is completed.
|
|
|
|
|
|
|
|
|
|
|
7 |
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @since 2.0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
*/
|
11 |
|
12 |
namespace WooCommerce\Square\Emails;
|
13 |
|
14 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
15 |
|
16 |
defined( 'ABSPATH' ) || exit;
|
17 |
|
214 |
);
|
215 |
|
216 |
// TODO update handling when WooCommerce 3.2 is the minimum required version {FN 2019-05-03}
|
217 |
+
if ( Plugin_Compatibility::is_wc_version_gte( '3.2' ) ) {
|
218 |
foreach ( $email_merge_tags as $find => $replace ) {
|
219 |
$this->placeholders[ '{' . $find . '}' ] = $replace;
|
220 |
}
|
includes/Framework/Addresses/Address.php
ADDED
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Addresses;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* The base address data class.
|
8 |
+
*
|
9 |
+
* This serves as a standard address object to be passed around by plugins whenever dealing with address data, and
|
10 |
+
* eliminates the need to rely on WooCommerce's address arrays.
|
11 |
+
*
|
12 |
+
* @since 3.0.0
|
13 |
+
*/
|
14 |
+
class Address {
|
15 |
+
|
16 |
+
|
17 |
+
/** @var string line 1 of the street address */
|
18 |
+
protected $line_1 = '';
|
19 |
+
|
20 |
+
/** @var string line 2 of the street address */
|
21 |
+
protected $line_2 = '';
|
22 |
+
|
23 |
+
/** @var string line 3 of the street address */
|
24 |
+
protected $line_3 = '';
|
25 |
+
|
26 |
+
/** @var string address locality (city) */
|
27 |
+
protected $locality = '';
|
28 |
+
|
29 |
+
/** @var string address region (state) */
|
30 |
+
protected $region = '';
|
31 |
+
|
32 |
+
/** @var string address country */
|
33 |
+
protected $country = '';
|
34 |
+
|
35 |
+
/** @var string address postcode */
|
36 |
+
protected $postcode = '';
|
37 |
+
|
38 |
+
|
39 |
+
/** Getter methods ************************************************************************************************/
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Gets line 1 of the street address.
|
44 |
+
*
|
45 |
+
* @since 3.0.0
|
46 |
+
*
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function get_line_1() {
|
50 |
+
|
51 |
+
return $this->line_1;
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Gets line 2 of the street address.
|
57 |
+
*
|
58 |
+
* @since 3.0.0
|
59 |
+
*
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
public function get_line_2() {
|
63 |
+
|
64 |
+
return $this->line_2;
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Gets line 3 of the street address.
|
70 |
+
*
|
71 |
+
* @since 3.0.0
|
72 |
+
*
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function get_line_3() {
|
76 |
+
|
77 |
+
return $this->line_3;
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Gets the locality or city.
|
83 |
+
*
|
84 |
+
* @since 3.0.0
|
85 |
+
*
|
86 |
+
* @return string
|
87 |
+
*/
|
88 |
+
public function get_locality() {
|
89 |
+
|
90 |
+
return $this->locality;
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Gets the region or state.
|
96 |
+
*
|
97 |
+
* @since 3.0.0
|
98 |
+
*
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function get_region() {
|
102 |
+
|
103 |
+
return $this->region;
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Gets the country.
|
109 |
+
*
|
110 |
+
* @since 3.0.0
|
111 |
+
*
|
112 |
+
* @return string
|
113 |
+
*/
|
114 |
+
public function get_country() {
|
115 |
+
|
116 |
+
return $this->country;
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Gets the postcode.
|
122 |
+
*
|
123 |
+
* @since 3.0.0
|
124 |
+
*
|
125 |
+
* @return string
|
126 |
+
*/
|
127 |
+
public function get_postcode() {
|
128 |
+
|
129 |
+
return $this->postcode;
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Gets the hash representation of this address.
|
135 |
+
*
|
136 |
+
* @see Address::get_hash_data()
|
137 |
+
*
|
138 |
+
* @since 3.0.0
|
139 |
+
*
|
140 |
+
* @return string
|
141 |
+
*/
|
142 |
+
public function get_hash() {
|
143 |
+
|
144 |
+
return md5( wp_json_encode( $this->get_hash_data() ) );
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Gets the data used to generate a hash for the address.
|
150 |
+
*
|
151 |
+
* @since 3.0.0
|
152 |
+
*
|
153 |
+
* @return string[]
|
154 |
+
*/
|
155 |
+
protected function get_hash_data() {
|
156 |
+
|
157 |
+
return array(
|
158 |
+
$this->get_line_1(),
|
159 |
+
$this->get_line_2(),
|
160 |
+
$this->get_line_3(),
|
161 |
+
$this->get_locality(),
|
162 |
+
$this->get_region(),
|
163 |
+
$this->get_country(),
|
164 |
+
$this->get_postcode(),
|
165 |
+
);
|
166 |
+
}
|
167 |
+
|
168 |
+
|
169 |
+
/** Setter methods ************************************************************************************************/
|
170 |
+
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Sets line 1 of the street address.
|
174 |
+
*
|
175 |
+
* @since 3.0.0
|
176 |
+
*
|
177 |
+
* @param string $value line 1 value
|
178 |
+
*/
|
179 |
+
public function set_line_1( $value ) {
|
180 |
+
|
181 |
+
$this->line_1 = $value;
|
182 |
+
}
|
183 |
+
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Sets line 2 of the street address.
|
187 |
+
*
|
188 |
+
* @since 3.0.0
|
189 |
+
*
|
190 |
+
* @param string $value line 2 value
|
191 |
+
*/
|
192 |
+
public function set_line_2( $value ) {
|
193 |
+
|
194 |
+
$this->line_2 = $value;
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Gets line 3 of the street address.
|
200 |
+
*
|
201 |
+
* @since 3.0.0
|
202 |
+
*
|
203 |
+
* @param string $value line 3 value
|
204 |
+
*/
|
205 |
+
public function set_line_3( $value ) {
|
206 |
+
|
207 |
+
$this->line_3 = $value;
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Gets the locality or city.
|
213 |
+
*
|
214 |
+
* @since 3.0.0
|
215 |
+
*
|
216 |
+
* @param string $value locality value
|
217 |
+
*/
|
218 |
+
public function set_locality( $value ) {
|
219 |
+
|
220 |
+
$this->locality = $value;
|
221 |
+
}
|
222 |
+
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Gets the region or state.
|
226 |
+
*
|
227 |
+
* @since 3.0.0
|
228 |
+
*
|
229 |
+
* @param string $value region value
|
230 |
+
*/
|
231 |
+
public function set_region( $value ) {
|
232 |
+
|
233 |
+
$this->region = $value;
|
234 |
+
}
|
235 |
+
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Sets the country.
|
239 |
+
*
|
240 |
+
* @since 3.0.0
|
241 |
+
*
|
242 |
+
* @param string $value country value
|
243 |
+
*/
|
244 |
+
public function set_country( $value ) {
|
245 |
+
|
246 |
+
$this->country = $value;
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Sets the postcode.
|
252 |
+
*
|
253 |
+
* @since 3.0.0
|
254 |
+
*
|
255 |
+
* @param string $value postcode value
|
256 |
+
*/
|
257 |
+
public function set_postcode( $value ) {
|
258 |
+
|
259 |
+
$this->postcode = $value;
|
260 |
+
}
|
261 |
+
|
262 |
+
|
263 |
+
}
|
includes/Framework/Addresses/Customer_Address.php
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Addresses;
|
3 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* The customer address data class.
|
9 |
+
*
|
10 |
+
* Adds customer-specific data to a base address, as used for a billing or shipping address that can include first
|
11 |
+
* and last name.
|
12 |
+
*
|
13 |
+
* @see Address
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Customer_Address extends Address {
|
18 |
+
|
19 |
+
|
20 |
+
/** @var string customer first name */
|
21 |
+
protected $first_name = '';
|
22 |
+
|
23 |
+
/** @var string customer last name */
|
24 |
+
protected $last_name = '';
|
25 |
+
|
26 |
+
|
27 |
+
/** Getter Methods ************************************************************************************************/
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Gets the customer first name.
|
32 |
+
*
|
33 |
+
* @since 3.0.0
|
34 |
+
*
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public function get_first_name() {
|
38 |
+
|
39 |
+
return $this->first_name;
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Gets the customer first name.
|
45 |
+
*
|
46 |
+
* @since 3.0.0
|
47 |
+
*
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function get_last_name() {
|
51 |
+
|
52 |
+
return $this->last_name;
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Gets the data used to generate a hash for the address.
|
58 |
+
*
|
59 |
+
* @see Address::get_hash_data()
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
*
|
63 |
+
* @return string[]
|
64 |
+
*/
|
65 |
+
protected function get_hash_data() {
|
66 |
+
|
67 |
+
// add the first & last name to data used to generate the hash
|
68 |
+
$data = array_merge(
|
69 |
+
array(
|
70 |
+
$this->get_first_name(),
|
71 |
+
$this->get_last_name(),
|
72 |
+
),
|
73 |
+
parent::get_hash_data()
|
74 |
+
);
|
75 |
+
|
76 |
+
return $data;
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
/** Setter Methods ************************************************************************************************/
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Sets the customer first name.
|
85 |
+
*
|
86 |
+
* @since 3.0.0
|
87 |
+
*
|
88 |
+
* @param string $value first name value
|
89 |
+
*/
|
90 |
+
public function set_first_name( $value ) {
|
91 |
+
|
92 |
+
$this->first_name = $value;
|
93 |
+
}
|
94 |
+
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Sets the customer last name.
|
98 |
+
*
|
99 |
+
* @since 3.0.0
|
100 |
+
*
|
101 |
+
* @param string $value first name value
|
102 |
+
*/
|
103 |
+
public function set_last_name( $value ) {
|
104 |
+
|
105 |
+
$this->last_name = $value;
|
106 |
+
}
|
107 |
+
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Sets the full address based on a WooCommerce order.
|
111 |
+
*
|
112 |
+
* @since 3.0.0
|
113 |
+
*
|
114 |
+
* @param \WC_Order $order WooCommerce order object
|
115 |
+
* @param string $type address type, like billing or shipping
|
116 |
+
*/
|
117 |
+
public function set_from_order( \WC_Order $order, $type = 'billing' ) {
|
118 |
+
|
119 |
+
$this->set_first_name( Order_Compatibility::get_prop( $order, "{$type}_first_name" ) );
|
120 |
+
$this->set_last_name( Order_Compatibility::get_prop( $order, "{$type}_last_name" ) );
|
121 |
+
$this->set_line_1( Order_Compatibility::get_prop( $order, "{$type}_address_1" ) );
|
122 |
+
$this->set_line_2( Order_Compatibility::get_prop( $order, "{$type}_address_2" ) );
|
123 |
+
$this->set_locality( Order_Compatibility::get_prop( $order, "{$type}_city" ) );
|
124 |
+
$this->set_region( Order_Compatibility::get_prop( $order, "{$type}_state" ) );
|
125 |
+
$this->set_country( Order_Compatibility::get_prop( $order, "{$type}_country" ) );
|
126 |
+
$this->set_postcode( Order_Compatibility::get_prop( $order, "{$type}_postcode" ) );
|
127 |
+
}
|
128 |
+
}
|
includes/Framework/Admin_Message_Handler.php
ADDED
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* # WordPress Admin Message Handler Class
|
8 |
+
*
|
9 |
+
* This class provides a reusable wordpress admin messaging facility for setting
|
10 |
+
* and displaying messages and error messages across admin page requests without
|
11 |
+
* resorting to passing the messages as query vars.
|
12 |
+
*
|
13 |
+
* ## Usage
|
14 |
+
*
|
15 |
+
* To use simple instantiate the class then set one or more messages:
|
16 |
+
*
|
17 |
+
* `
|
18 |
+
* $admin_message_handler = new WP_Admin_Message_Handler( __FILE__ );
|
19 |
+
* $admin_message_handler->add_message( 'Hello World!' );
|
20 |
+
* `
|
21 |
+
*
|
22 |
+
* Then show the messages wherever you need, either with the built-in method
|
23 |
+
* or by writing your own:
|
24 |
+
*
|
25 |
+
* `$admin_message_handler->show_messages();`
|
26 |
+
*/
|
27 |
+
class Admin_Message_Handler {
|
28 |
+
|
29 |
+
|
30 |
+
/** transient message prefix */
|
31 |
+
const MESSAGE_TRANSIENT_PREFIX = '_wp_admin_message_';
|
32 |
+
|
33 |
+
/** the message id GET name */
|
34 |
+
const MESSAGE_ID_GET_NAME = 'wpamhid';
|
35 |
+
|
36 |
+
|
37 |
+
/** @var string unique message identifier, defaults to __FILE__ unless otherwise set */
|
38 |
+
private $message_id;
|
39 |
+
|
40 |
+
/** @var array array of messages */
|
41 |
+
private $messages = array();
|
42 |
+
|
43 |
+
/** @var array array of error messages */
|
44 |
+
private $errors = array();
|
45 |
+
|
46 |
+
/** @var array array of warning messages */
|
47 |
+
private $warnings = array();
|
48 |
+
|
49 |
+
/** @var array array of info messages */
|
50 |
+
private $infos = array();
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Construct and initialize the admin message handler class
|
55 |
+
*
|
56 |
+
* @since 3.0.0
|
57 |
+
* @param string $message_id optional message id. Best practice is to set
|
58 |
+
* this to a unique identifier based on the client plugin, such as __FILE__
|
59 |
+
*/
|
60 |
+
public function __construct( $message_id = null ) {
|
61 |
+
|
62 |
+
$this->message_id = $message_id;
|
63 |
+
|
64 |
+
// load any available messages
|
65 |
+
$this->load_messages();
|
66 |
+
|
67 |
+
add_filter( 'wp_redirect', array( $this, 'redirect' ), 1, 2 );
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Persist messages
|
73 |
+
*
|
74 |
+
* @since 3.0.0
|
75 |
+
* @return boolean true if any messages were set, false otherwise
|
76 |
+
*/
|
77 |
+
public function set_messages() {
|
78 |
+
|
79 |
+
// any messages to persist?
|
80 |
+
if ( $this->message_count() > 0 || $this->info_count() > 0 || $this->warning_count() > 0 || $this->error_count() > 0 ) {
|
81 |
+
|
82 |
+
set_transient(
|
83 |
+
self::MESSAGE_TRANSIENT_PREFIX . $this->get_message_id(),
|
84 |
+
array(
|
85 |
+
'errors' => $this->errors,
|
86 |
+
'warnings' => $this->warnings,
|
87 |
+
'infos' => $this->infos,
|
88 |
+
'messages' => $this->messages,
|
89 |
+
),
|
90 |
+
60 * 60
|
91 |
+
);
|
92 |
+
|
93 |
+
return true;
|
94 |
+
}
|
95 |
+
|
96 |
+
return false;
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Loads messages
|
102 |
+
*
|
103 |
+
* @since 3.0.0
|
104 |
+
*/
|
105 |
+
public function load_messages() {
|
106 |
+
|
107 |
+
if ( isset( $_GET[ self::MESSAGE_ID_GET_NAME ] ) && $this->get_message_id() == $_GET[ self::MESSAGE_ID_GET_NAME ] ) {
|
108 |
+
|
109 |
+
$memo = get_transient( self::MESSAGE_TRANSIENT_PREFIX . $_GET[ self::MESSAGE_ID_GET_NAME ] );
|
110 |
+
|
111 |
+
if ( isset( $memo['errors'] ) ) $this->errors = $memo['errors'];
|
112 |
+
if ( isset( $memo['warnings'] ) ) $this->warnings = $memo['warnings'];
|
113 |
+
if ( isset( $memo['infos'] ) ) $this->infos = $memo['infos'];
|
114 |
+
if ( isset( $memo['messages'] ) ) $this->messages = $memo['messages'];
|
115 |
+
|
116 |
+
$this->clear_messages( $_GET[ self::MESSAGE_ID_GET_NAME ] );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Clear messages and errors
|
123 |
+
*
|
124 |
+
* @since 3.0.0
|
125 |
+
* @param string $id the messages identifier
|
126 |
+
*/
|
127 |
+
public function clear_messages( $id ) {
|
128 |
+
delete_transient( self::MESSAGE_TRANSIENT_PREFIX . $id );
|
129 |
+
}
|
130 |
+
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Add an error message.
|
134 |
+
*
|
135 |
+
* @since 3.0.0
|
136 |
+
* @param string $error error message
|
137 |
+
*/
|
138 |
+
public function add_error( $error ) {
|
139 |
+
$this->errors[] = $error;
|
140 |
+
}
|
141 |
+
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Adds a warning message.
|
145 |
+
*
|
146 |
+
* @since 3.0.0
|
147 |
+
*
|
148 |
+
* @param string $message warning message to add
|
149 |
+
*/
|
150 |
+
public function add_warning( $message ) {
|
151 |
+
$this->warnings[] = $message;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Add a message.
|
156 |
+
*
|
157 |
+
* @since 3.0.0
|
158 |
+
* @param string $message the message to add
|
159 |
+
*/
|
160 |
+
public function add_message( $message ) {
|
161 |
+
$this->messages[] = $message;
|
162 |
+
}
|
163 |
+
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Get error count.
|
167 |
+
*
|
168 |
+
* @since 3.0.0
|
169 |
+
* @return int error message count
|
170 |
+
*/
|
171 |
+
public function error_count() {
|
172 |
+
return sizeof( $this->errors );
|
173 |
+
}
|
174 |
+
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Gets the warning message count.
|
178 |
+
*
|
179 |
+
* @since 3.0.0
|
180 |
+
*
|
181 |
+
* @return int warning message count
|
182 |
+
*/
|
183 |
+
public function warning_count() {
|
184 |
+
return sizeof( $this->warnings );
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Gets the info message count.
|
190 |
+
*
|
191 |
+
* @since 3.0.0
|
192 |
+
*
|
193 |
+
* @return int info message count
|
194 |
+
*/
|
195 |
+
public function info_count() {
|
196 |
+
return sizeof( $this->infos );
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Get message count.
|
202 |
+
*
|
203 |
+
* @since 3.0.0
|
204 |
+
* @return int message count
|
205 |
+
*/
|
206 |
+
public function message_count() {
|
207 |
+
return sizeof( $this->messages );
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Get error messages
|
213 |
+
*
|
214 |
+
* @since 3.0.0
|
215 |
+
* @return array of error message strings
|
216 |
+
*/
|
217 |
+
public function get_errors() {
|
218 |
+
return $this->errors;
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Get an error message
|
224 |
+
*
|
225 |
+
* @since 3.0.0
|
226 |
+
* @param int $index the error index
|
227 |
+
* @return string the error message
|
228 |
+
*/
|
229 |
+
public function get_error( $index ) {
|
230 |
+
return isset( $this->errors[ $index ] ) ? $this->errors[ $index ] : '';
|
231 |
+
}
|
232 |
+
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Gets all warning messages.
|
236 |
+
*
|
237 |
+
* @since 3.0.0
|
238 |
+
*
|
239 |
+
* @return array
|
240 |
+
*/
|
241 |
+
public function get_warnings() {
|
242 |
+
return $this->warnings;
|
243 |
+
}
|
244 |
+
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Gets a specific warning message.
|
248 |
+
*
|
249 |
+
* @since 3.0.0
|
250 |
+
*
|
251 |
+
* @param int $index warning message index
|
252 |
+
* @return string
|
253 |
+
*/
|
254 |
+
public function get_warning( $index ) {
|
255 |
+
return isset( $this->warnings[ $index ] ) ? $this->warnings[ $index ] : '';
|
256 |
+
}
|
257 |
+
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Gets all info messages.
|
261 |
+
*
|
262 |
+
* @since 3.0.0
|
263 |
+
*
|
264 |
+
* @return array
|
265 |
+
*/
|
266 |
+
public function get_infos() {
|
267 |
+
return $this->infos;
|
268 |
+
}
|
269 |
+
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Gets a specific info message.
|
273 |
+
*
|
274 |
+
* @since 3.0.0
|
275 |
+
*
|
276 |
+
* @param int $index info message index
|
277 |
+
* @return string
|
278 |
+
*/
|
279 |
+
public function get_info( $index ) {
|
280 |
+
return isset( $this->infos[ $index ] ) ? $this->infos[ $index ] : '';
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Get messages
|
286 |
+
*
|
287 |
+
* @since 3.0.0
|
288 |
+
* @return array of message strings
|
289 |
+
*/
|
290 |
+
public function get_messages() {
|
291 |
+
return $this->messages;
|
292 |
+
}
|
293 |
+
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Get a message
|
297 |
+
*
|
298 |
+
* @since 3.0.0
|
299 |
+
* @param int $index the message index
|
300 |
+
* @return string the message
|
301 |
+
*/
|
302 |
+
public function get_message( $index ) {
|
303 |
+
return isset( $this->messages[ $index ] ) ? $this->messages[ $index ] : '';
|
304 |
+
}
|
305 |
+
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Render the errors and messages.
|
309 |
+
*
|
310 |
+
* @since 3.0.0
|
311 |
+
* @param array $params {
|
312 |
+
* Optional parameters.
|
313 |
+
*
|
314 |
+
* @type array $capabilities Any user capabilities to check if the user is allowed to view the messages,
|
315 |
+
* default: `manage_woocommerce`
|
316 |
+
* }
|
317 |
+
*/
|
318 |
+
public function show_messages( $params = array() ) {
|
319 |
+
|
320 |
+
$params = wp_parse_args( $params, array(
|
321 |
+
'capabilities' => array(
|
322 |
+
'manage_woocommerce',
|
323 |
+
),
|
324 |
+
) );
|
325 |
+
|
326 |
+
$check_user_capabilities = array();
|
327 |
+
|
328 |
+
// check if user has at least one capability that allows to see messages
|
329 |
+
foreach ( $params['capabilities'] as $capability ) {
|
330 |
+
$check_user_capabilities[] = current_user_can( $capability );
|
331 |
+
}
|
332 |
+
|
333 |
+
// bail out if user has no minimum capabilities to see messages
|
334 |
+
if ( ! in_array( true, $check_user_capabilities, true ) ) {
|
335 |
+
return;
|
336 |
+
}
|
337 |
+
|
338 |
+
$output = '';
|
339 |
+
|
340 |
+
if ( $this->error_count() > 0 ) {
|
341 |
+
$output .= '<div id="wp-admin-message-handler-error" class="notice-error notice"><ul><li><strong>' . implode( '</strong></li><li><strong>', $this->get_errors() ) . '</strong></li></ul></div>';
|
342 |
+
}
|
343 |
+
|
344 |
+
if ( $this->warning_count() > 0 ) {
|
345 |
+
$output .= '<div id="wp-admin-message-handler-warning" class="notice-warning notice"><ul><li><strong>' . implode( '</strong></li><li><strong>', $this->get_warnings() ) . '</strong></li></ul></div>';
|
346 |
+
}
|
347 |
+
|
348 |
+
if ( $this->info_count() > 0 ) {
|
349 |
+
$output .= '<div id="wp-admin-message-handler-warning" class="notice-info notice"><ul><li><strong>' . implode( '</strong></li><li><strong>', $this->get_infos() ) . '</strong></li></ul></div>';
|
350 |
+
}
|
351 |
+
|
352 |
+
if ( $this->message_count() > 0 ) {
|
353 |
+
$output .= '<div id="wp-admin-message-handler-message" class="notice-success notice"><ul><li><strong>' . implode( '</strong></li><li><strong>', $this->get_messages() ) . '</strong></li></ul></div>';
|
354 |
+
}
|
355 |
+
|
356 |
+
echo wp_kses_post( $output );
|
357 |
+
}
|
358 |
+
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Redirection hook which persists messages into session data.
|
362 |
+
*
|
363 |
+
* @since 3.0.0
|
364 |
+
* @param string $location the URL to redirect to
|
365 |
+
* @param int $status the http status
|
366 |
+
* @return string the URL to redirect to
|
367 |
+
*/
|
368 |
+
public function redirect( $location, $status ) {
|
369 |
+
|
370 |
+
// add the admin message id param to the
|
371 |
+
if ( $this->set_messages() ) {
|
372 |
+
$location = add_query_arg( self::MESSAGE_ID_GET_NAME, rawurlencode( $this->get_message_id() ), $location );
|
373 |
+
}
|
374 |
+
|
375 |
+
return $location;
|
376 |
+
}
|
377 |
+
|
378 |
+
|
379 |
+
/**
|
380 |
+
* Generate a unique id to identify the messages
|
381 |
+
*
|
382 |
+
* @since 3.0.0
|
383 |
+
* @return string unique identifier
|
384 |
+
*/
|
385 |
+
protected function get_message_id() {
|
386 |
+
|
387 |
+
if ( ! isset( $this->message_id ) ) $this->message_id = __FILE__;
|
388 |
+
|
389 |
+
return wp_create_nonce( $this->message_id );
|
390 |
+
|
391 |
+
}
|
392 |
+
}
|
includes/Framework/Admin_Notice_Handler.php
ADDED
@@ -0,0 +1,380 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Admin Notice Handler Class
|
8 |
+
*
|
9 |
+
* The purpose of this class is to provide a facility for displaying
|
10 |
+
* conditional (often dismissible) admin notices during a single page
|
11 |
+
* request
|
12 |
+
*
|
13 |
+
* @since 3.0.0
|
14 |
+
*/
|
15 |
+
class Admin_Notice_Handler {
|
16 |
+
|
17 |
+
|
18 |
+
/** @var Plugin the plugin */
|
19 |
+
private $plugin;
|
20 |
+
|
21 |
+
/** @var array associative array of id to notice text */
|
22 |
+
private $admin_notices = array();
|
23 |
+
|
24 |
+
/** @var boolean static member to enforce a single rendering of the admin notice placeholder element */
|
25 |
+
static private $admin_notice_placeholder_rendered = false;
|
26 |
+
|
27 |
+
/** @var boolean static member to enforce a single rendering of the admin notice javascript */
|
28 |
+
static private $admin_notice_js_rendered = false;
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Initialize and setup the Admin Notice Handler
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
*/
|
36 |
+
public function __construct( $plugin ) {
|
37 |
+
|
38 |
+
$this->plugin = $plugin;
|
39 |
+
|
40 |
+
// render any admin notices, delayed notices, and
|
41 |
+
add_action( 'admin_notices', array( $this, 'render_admin_notices' ), 15 );
|
42 |
+
add_action( 'admin_footer', array( $this, 'render_delayed_admin_notices' ), 15 );
|
43 |
+
add_action( 'admin_footer', array( $this, 'render_admin_notice_js' ), 20 );
|
44 |
+
|
45 |
+
// AJAX handler to dismiss any warning/error notices
|
46 |
+
add_action( 'wp_ajax_wc_plugin_framework_' . $this->get_plugin()->get_id() . '_dismiss_notice', array( $this, 'handle_dismiss_notice' ) );
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Adds the given $message as a dismissible notice identified by $message_id,
|
52 |
+
* unless the notice has been dismissed, or we're on the plugin settings page
|
53 |
+
*
|
54 |
+
* @since 3.0.0
|
55 |
+
* @param string $message the notice message to display
|
56 |
+
* @param string $message_id the message id
|
57 |
+
* @param array $params {
|
58 |
+
* Optional parameters.
|
59 |
+
*
|
60 |
+
* @type bool $dismissible If the notice should be dismissible
|
61 |
+
* @type bool $always_show_on_settings If the notice should be forced to display on the
|
62 |
+
* plugin settings page, regardless of `$dismissible`.
|
63 |
+
* @type string $notice_class Additional classes for the notice.
|
64 |
+
* }
|
65 |
+
*/
|
66 |
+
public function add_admin_notice( $message, $message_id, $params = array() ) {
|
67 |
+
|
68 |
+
$params = wp_parse_args( $params, array(
|
69 |
+
'dismissible' => true,
|
70 |
+
'always_show_on_settings' => true,
|
71 |
+
'notice_class' => 'updated',
|
72 |
+
) );
|
73 |
+
|
74 |
+
if ( $this->should_display_notice( $message_id, $params ) ) {
|
75 |
+
$this->admin_notices[ $message_id ] = array(
|
76 |
+
'message' => $message,
|
77 |
+
'rendered' => false,
|
78 |
+
'params' => $params,
|
79 |
+
);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Returns true if the identified notice hasn't been cleared, or we're on
|
86 |
+
* the plugin settings page (where notices are always displayed)
|
87 |
+
*
|
88 |
+
* @since 3.0.0
|
89 |
+
* @param string $message_id the message id
|
90 |
+
* @param array $params {
|
91 |
+
* Optional parameters.
|
92 |
+
*
|
93 |
+
* @type bool $dismissible If the notice should be dismissible
|
94 |
+
* @type bool $always_show_on_settings If the notice should be forced to display on the
|
95 |
+
* plugin settings page, regardless of `$dismissible`.
|
96 |
+
* }
|
97 |
+
* @return bool
|
98 |
+
*/
|
99 |
+
public function should_display_notice( $message_id, $params = array() ) {
|
100 |
+
|
101 |
+
// bail out if user is not a shop manager
|
102 |
+
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
|
106 |
+
$params = wp_parse_args( $params, array(
|
107 |
+
'dismissible' => true,
|
108 |
+
'always_show_on_settings' => true,
|
109 |
+
) );
|
110 |
+
|
111 |
+
// if the notice is always shown on the settings page, and we're on the settings page
|
112 |
+
if ( $params['always_show_on_settings'] && $this->get_plugin()->is_plugin_settings() ) {
|
113 |
+
return true;
|
114 |
+
}
|
115 |
+
|
116 |
+
// non-dismissible, always display
|
117 |
+
if ( ! $params['dismissible'] ) {
|
118 |
+
return true;
|
119 |
+
}
|
120 |
+
|
121 |
+
// dismissible: display if notice has not been dismissed
|
122 |
+
return ! $this->is_notice_dismissed( $message_id );
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Render any admin notices, as well as the admin notice placeholder
|
128 |
+
*
|
129 |
+
* @since 3.0.0
|
130 |
+
* @param boolean $is_visible true if the notices should be immediately visible, false otherwise
|
131 |
+
*/
|
132 |
+
public function render_admin_notices( $is_visible = true ) {
|
133 |
+
|
134 |
+
// default for actions
|
135 |
+
if ( ! is_bool( $is_visible ) ) {
|
136 |
+
$is_visible = true;
|
137 |
+
}
|
138 |
+
|
139 |
+
foreach ( $this->admin_notices as $message_id => $message_data ) {
|
140 |
+
if ( ! $message_data['rendered'] ) {
|
141 |
+
$message_data['params']['is_visible'] = $is_visible;
|
142 |
+
$this->render_admin_notice( $message_data['message'], $message_id, $message_data['params'] );
|
143 |
+
$this->admin_notices[ $message_id ]['rendered'] = true;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
if ( $is_visible && ! self::$admin_notice_placeholder_rendered ) {
|
148 |
+
// placeholder for moving delayed notices up into place
|
149 |
+
echo '<div class="js-wc-' . esc_attr( $this->get_plugin()->get_id_dasherized() ) . '-admin-notice-placeholder"></div>';
|
150 |
+
self::$admin_notice_placeholder_rendered = true;
|
151 |
+
}
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Render any delayed admin notices, which have not yet already been rendered
|
158 |
+
*
|
159 |
+
* @since 3.0.0
|
160 |
+
*/
|
161 |
+
public function render_delayed_admin_notices() {
|
162 |
+
$this->render_admin_notices( false );
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Render a single admin notice
|
168 |
+
*
|
169 |
+
* @since 3.0.0
|
170 |
+
* @param string $message the notice message to display
|
171 |
+
* @param string $message_id the message id
|
172 |
+
* @param array $params {
|
173 |
+
* Optional parameters.
|
174 |
+
*
|
175 |
+
* @type bool $dismissible If the notice should be dismissible
|
176 |
+
* @type bool $is_visible If the notice should be immediately visible
|
177 |
+
* @type bool $always_show_on_settings If the notice should be forced to display on the
|
178 |
+
* plugin settings page, regardless of `$dismissible`.
|
179 |
+
* @type string $notice_class Additional classes for the notice.
|
180 |
+
* }
|
181 |
+
*/
|
182 |
+
public function render_admin_notice( $message, $message_id, $params = array() ) {
|
183 |
+
|
184 |
+
$params = wp_parse_args( $params, array(
|
185 |
+
'dismissible' => true,
|
186 |
+
'is_visible' => true,
|
187 |
+
'always_show_on_settings' => true,
|
188 |
+
'notice_class' => 'updated',
|
189 |
+
) );
|
190 |
+
|
191 |
+
$classes = array(
|
192 |
+
'notice',
|
193 |
+
'js-wc-plugin-framework-admin-notice',
|
194 |
+
$params['notice_class'],
|
195 |
+
);
|
196 |
+
|
197 |
+
// maybe make this notice dismissible
|
198 |
+
// uses a WP core class which handles the markup and styling
|
199 |
+
if ( $params['dismissible'] && ( ! $params['always_show_on_settings'] || ! $this->get_plugin()->is_plugin_settings() ) ) {
|
200 |
+
$classes[] = 'is-dismissible';
|
201 |
+
}
|
202 |
+
|
203 |
+
echo sprintf(
|
204 |
+
'<div class="%1$s" data-plugin-id="%2$s" data-message-id="%3$s" %4$s><p>%5$s</p></div>',
|
205 |
+
esc_attr( implode( ' ', $classes ) ),
|
206 |
+
esc_attr( $this->get_plugin()->get_id() ),
|
207 |
+
esc_attr( $message_id ),
|
208 |
+
( ! $params['is_visible'] ) ? 'style="display:none;"' : '',
|
209 |
+
wp_kses_post( $message )
|
210 |
+
);
|
211 |
+
}
|
212 |
+
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Render the javascript to handle the notice "dismiss" functionality
|
216 |
+
*
|
217 |
+
* @since 3.0.0
|
218 |
+
*/
|
219 |
+
public function render_admin_notice_js() {
|
220 |
+
|
221 |
+
// if there were no notices, or we've already rendered the js, there's nothing to do
|
222 |
+
if ( empty( $this->admin_notices ) || self::$admin_notice_js_rendered ) {
|
223 |
+
return;
|
224 |
+
}
|
225 |
+
|
226 |
+
$plugin_slug = $this->get_plugin()->get_id_dasherized();
|
227 |
+
|
228 |
+
self::$admin_notice_js_rendered = true;
|
229 |
+
|
230 |
+
ob_start();
|
231 |
+
?>
|
232 |
+
|
233 |
+
// Log dismissed notices
|
234 |
+
$( '.js-wc-plugin-framework-admin-notice' ).on( 'click.wp-dismiss-notice', '.notice-dismiss', function( e ) {
|
235 |
+
|
236 |
+
var $notice = $( this ).closest( '.js-wc-plugin-framework-admin-notice' );
|
237 |
+
|
238 |
+
log_dismissed_notice(
|
239 |
+
$( $notice ).data( 'plugin-id' ),
|
240 |
+
$( $notice ).data( 'message-id' )
|
241 |
+
);
|
242 |
+
|
243 |
+
} );
|
244 |
+
|
245 |
+
// Log and hide legacy notices
|
246 |
+
$( 'a.js-wc-plugin-framework-notice-dismiss' ).click( function( e ) {
|
247 |
+
|
248 |
+
e.preventDefault();
|
249 |
+
|
250 |
+
var $notice = $( this ).closest( '.js-wc-plugin-framework-admin-notice' );
|
251 |
+
|
252 |
+
log_dismissed_notice(
|
253 |
+
$( $notice ).data( 'plugin-id' ),
|
254 |
+
$( $notice ).data( 'message-id' )
|
255 |
+
);
|
256 |
+
|
257 |
+
$( $notice ).fadeOut();
|
258 |
+
|
259 |
+
} );
|
260 |
+
|
261 |
+
function log_dismissed_notice( pluginID, messageID ) {
|
262 |
+
|
263 |
+
$.get(
|
264 |
+
ajaxurl,
|
265 |
+
{
|
266 |
+
action: 'wc_plugin_framework_' + pluginID + '_dismiss_notice',
|
267 |
+
messageid: messageID
|
268 |
+
}
|
269 |
+
);
|
270 |
+
}
|
271 |
+
|
272 |
+
// move any delayed notices up into position .show();
|
273 |
+
$( '.js-wc-plugin-framework-admin-notice:hidden' ).insertAfter( '.js-wc-<?php echo esc_js( $plugin_slug ); ?>-admin-notice-placeholder' ).show();
|
274 |
+
<?php
|
275 |
+
$javascript = ob_get_clean();
|
276 |
+
|
277 |
+
wc_enqueue_js( $javascript );
|
278 |
+
}
|
279 |
+
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Marks the identified admin notice as dismissed for the given user
|
283 |
+
*
|
284 |
+
* @since 3.0.0
|
285 |
+
* @param string $message_id the message identifier
|
286 |
+
* @param int $user_id optional user identifier, defaults to current user
|
287 |
+
*/
|
288 |
+
public function dismiss_notice( $message_id, $user_id = null ) {
|
289 |
+
|
290 |
+
if ( is_null( $user_id ) ) {
|
291 |
+
$user_id = get_current_user_id();
|
292 |
+
}
|
293 |
+
|
294 |
+
$dismissed_notices = $this->get_dismissed_notices( $user_id );
|
295 |
+
|
296 |
+
$dismissed_notices[ $message_id ] = true;
|
297 |
+
|
298 |
+
update_user_meta( $user_id, '_wc_plugin_framework_' . $this->get_plugin()->get_id() . '_dismissed_messages', $dismissed_notices );
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Admin Notice Dismissed Action.
|
302 |
+
*
|
303 |
+
* Fired when a user dismisses an admin notice.
|
304 |
+
*
|
305 |
+
* @since 3.0.0
|
306 |
+
* @param string $message_id notice identifier
|
307 |
+
* @param string|int $user_id
|
308 |
+
*/
|
309 |
+
do_action( 'wc_' . $this->get_plugin()->get_id(). '_dismiss_notice', $message_id, $user_id );
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Returns true if the identified admin notice has been dismissed for the
|
314 |
+
* given user
|
315 |
+
*
|
316 |
+
* @since 3.0.0
|
317 |
+
* @param string $message_id the message identifier
|
318 |
+
* @param int $user_id optional user identifier, defaults to current user
|
319 |
+
* @return boolean true if the message has been dismissed by the admin user
|
320 |
+
*/
|
321 |
+
public function is_notice_dismissed( $message_id, $user_id = null ) {
|
322 |
+
|
323 |
+
$dismissed_notices = $this->get_dismissed_notices( $user_id );
|
324 |
+
|
325 |
+
return isset( $dismissed_notices[ $message_id ] ) && $dismissed_notices[ $message_id ];
|
326 |
+
}
|
327 |
+
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Returns the full set of dismissed notices for the user identified by
|
331 |
+
* $user_id, for this plugin
|
332 |
+
*
|
333 |
+
* @since 3.0.0
|
334 |
+
* @param int $user_id optional user identifier, defaults to current user
|
335 |
+
* @return array of message id to dismissed status (true or false)
|
336 |
+
*/
|
337 |
+
public function get_dismissed_notices( $user_id = null ) {
|
338 |
+
|
339 |
+
if ( is_null( $user_id ) ) {
|
340 |
+
$user_id = get_current_user_id();
|
341 |
+
}
|
342 |
+
|
343 |
+
$dismissed_notices = get_user_meta( $user_id, '_wc_plugin_framework_' . $this->get_plugin()->get_id() . '_dismissed_messages', true );
|
344 |
+
|
345 |
+
if ( empty( $dismissed_notices ) ) {
|
346 |
+
return array();
|
347 |
+
} else {
|
348 |
+
return $dismissed_notices;
|
349 |
+
}
|
350 |
+
}
|
351 |
+
|
352 |
+
|
353 |
+
/** AJAX methods ******************************************************/
|
354 |
+
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Dismiss the identified notice
|
358 |
+
*
|
359 |
+
* @since 3.0.0
|
360 |
+
*/
|
361 |
+
public function handle_dismiss_notice() {
|
362 |
+
|
363 |
+
$this->dismiss_notice( $_REQUEST['messageid'] );
|
364 |
+
|
365 |
+
}
|
366 |
+
|
367 |
+
|
368 |
+
/** Getter methods ******************************************************/
|
369 |
+
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Get the plugin
|
373 |
+
*
|
374 |
+
* @since 3.0.0
|
375 |
+
* @return Plugin returns the plugin instance
|
376 |
+
*/
|
377 |
+
protected function get_plugin() {
|
378 |
+
return $this->plugin;
|
379 |
+
}
|
380 |
+
}
|
includes/Framework/Api/API_JSON_Request.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\Api;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Base JSON API request class.
|
9 |
+
*
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
abstract class API_JSON_Request implements API_Request {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var string The request method, one of HEAD, GET, PUT, PATCH, POST, DELETE */
|
16 |
+
protected $method;
|
17 |
+
|
18 |
+
/** @var string The request path */
|
19 |
+
protected $path;
|
20 |
+
|
21 |
+
/** @var array The request parameters, if any */
|
22 |
+
protected $params = array();
|
23 |
+
|
24 |
+
/** @var array the request data */
|
25 |
+
protected $data = array();
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get the request method.
|
30 |
+
*
|
31 |
+
* @since 3.0.0
|
32 |
+
* @see API_Request::get_method()
|
33 |
+
* @return string
|
34 |
+
*/
|
35 |
+
public function get_method() {
|
36 |
+
return $this->method;
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Get the request path.
|
42 |
+
*
|
43 |
+
* @since 3.0.0
|
44 |
+
* @see API_Request::get_path()
|
45 |
+
* @return string
|
46 |
+
*/
|
47 |
+
public function get_path() {
|
48 |
+
return $this->path;
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get the request parameters.
|
54 |
+
*
|
55 |
+
* @since 3.0.0
|
56 |
+
* @see API_Request::get_params()
|
57 |
+
* @return array
|
58 |
+
*/
|
59 |
+
public function get_params() {
|
60 |
+
return $this->params;
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Get the request data.
|
66 |
+
*
|
67 |
+
* @since 3.0.0
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
public function get_data() {
|
71 |
+
return $this->data;
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
/** API Helper Methods ******************************************************/
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Get the string representation of this request.
|
80 |
+
*
|
81 |
+
* @since 3.0.0
|
82 |
+
* @see API_Request::to_string()
|
83 |
+
* @return string
|
84 |
+
*/
|
85 |
+
public function to_string() {
|
86 |
+
|
87 |
+
$data = $this->get_data();
|
88 |
+
|
89 |
+
return ! empty( $data ) ? wp_json_encode( $data ) : '';
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Get the string representation of this request with any and all sensitive elements masked
|
95 |
+
* or removed.
|
96 |
+
*
|
97 |
+
* @since 3.0.0
|
98 |
+
* @see API_Request::to_string_safe()
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function to_string_safe() {
|
102 |
+
|
103 |
+
return $this->to_string();
|
104 |
+
}
|
105 |
+
}
|
includes/Framework/Api/API_JSON_Response.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\Api;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Base JSON API response class.
|
9 |
+
*
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
abstract class API_JSON_Response {
|
13 |
+
|
14 |
+
/** @var string string representation of this response */
|
15 |
+
protected $raw_response_json;
|
16 |
+
|
17 |
+
/** @var mixed decoded response data */
|
18 |
+
public $response_data;
|
19 |
+
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Build the data object from the raw JSON.
|
23 |
+
*
|
24 |
+
* @since 3.0.0
|
25 |
+
* @param string $raw_response_json The raw JSON
|
26 |
+
*/
|
27 |
+
public function __construct( $raw_response_json ) {
|
28 |
+
$this->raw_response_json = $raw_response_json;
|
29 |
+
$this->response_data = json_decode( $raw_response_json );
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Magic accessor for response data attributes
|
35 |
+
*
|
36 |
+
* @since 3.0.0
|
37 |
+
* @param string $name The attribute name to get.
|
38 |
+
* @return mixed The attribute value
|
39 |
+
*/
|
40 |
+
public function __get( $name ) {
|
41 |
+
// accessing the response_data object indirectly via attribute (useful when it's a class)
|
42 |
+
return isset( $this->response_data->$name ) ? $this->response_data->$name : null;
|
43 |
+
}
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Get the string representation of this response.
|
48 |
+
*
|
49 |
+
* @since 3.0.0
|
50 |
+
* @return string
|
51 |
+
*/
|
52 |
+
public function to_string() {
|
53 |
+
return $this->raw_response_json;
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Get the string representation of this response with any and all sensitive elements masked
|
59 |
+
* or removed.
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
* @return string
|
63 |
+
*/
|
64 |
+
public function to_string_safe() {
|
65 |
+
return $this->to_string();
|
66 |
+
}
|
67 |
+
}
|
includes/Framework/Api/API_Request.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Api;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
interface API_Request {
|
7 |
+
/**
|
8 |
+
* Returns the method for this request: one of HEAD, GET, PUT, PATCH, POST, DELETE
|
9 |
+
*
|
10 |
+
* @since 3.0.0
|
11 |
+
* @return string the request method, or null to use the API default
|
12 |
+
*/
|
13 |
+
public function get_method();
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Returns the request path
|
18 |
+
*
|
19 |
+
* @since 3.0.0
|
20 |
+
* @return string the request path, or '' if none
|
21 |
+
*/
|
22 |
+
public function get_path();
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Gets the request query params.
|
27 |
+
*
|
28 |
+
* @since 3.0.0
|
29 |
+
*
|
30 |
+
* @return array
|
31 |
+
*/
|
32 |
+
public function get_params();
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the request data.
|
37 |
+
*
|
38 |
+
* @since 3.0.0
|
39 |
+
*
|
40 |
+
* @return array
|
41 |
+
*/
|
42 |
+
public function get_data();
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Returns the string representation of this request
|
47 |
+
*
|
48 |
+
* @since 3.0.0
|
49 |
+
* @return string the request
|
50 |
+
*/
|
51 |
+
public function to_string();
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Returns the string representation of this request with any and all
|
56 |
+
* sensitive elements masked or removed
|
57 |
+
*
|
58 |
+
* @since 3.0.0
|
59 |
+
* @return string the request, safe for logging/displaying
|
60 |
+
*/
|
61 |
+
public function to_string_safe();
|
62 |
+
}
|
includes/Framework/Api/API_Response.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Api;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
interface API_Response {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Returns the string representation of this request
|
10 |
+
*
|
11 |
+
* @since 3.0.0
|
12 |
+
* @return string the request
|
13 |
+
*/
|
14 |
+
public function to_string();
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Returns the string representation of this request with any and all
|
19 |
+
* sensitive elements masked or removed
|
20 |
+
*
|
21 |
+
* @since 3.0.0
|
22 |
+
* @return string the request, safe for logging/displaying
|
23 |
+
*/
|
24 |
+
public function to_string_safe();
|
25 |
+
}
|
includes/Framework/Api/Base.php
ADDED
@@ -0,0 +1,659 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Api;
|
3 |
+
|
4 |
+
use WooCommerce;
|
5 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
6 |
+
|
7 |
+
defined( 'ABSPATH' ) or exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Base API Class
|
11 |
+
*
|
12 |
+
* This class provides a standardized framework for constructing an API wrapper
|
13 |
+
* to external services. It is designed to be extremely flexible.
|
14 |
+
*/
|
15 |
+
abstract class Base {
|
16 |
+
|
17 |
+
/** @var string request method, defaults to POST */
|
18 |
+
protected $request_method = 'POST';
|
19 |
+
|
20 |
+
/** @var string URI used for the request */
|
21 |
+
protected $request_uri;
|
22 |
+
|
23 |
+
/** @var array request headers */
|
24 |
+
protected $request_headers = array();
|
25 |
+
|
26 |
+
/** @var string request user-agent */
|
27 |
+
protected $request_user_agent;
|
28 |
+
|
29 |
+
/** @var string request HTTP version, defaults to 1.0 */
|
30 |
+
protected $request_http_version = '1.0';
|
31 |
+
|
32 |
+
/** @var string request duration */
|
33 |
+
protected $request_duration;
|
34 |
+
|
35 |
+
/** @var API_Request|object request */
|
36 |
+
protected $request;
|
37 |
+
|
38 |
+
/** @var string response code */
|
39 |
+
protected $response_code;
|
40 |
+
|
41 |
+
/** @var string response message */
|
42 |
+
protected $response_message;
|
43 |
+
|
44 |
+
/** @var array response headers */
|
45 |
+
protected $response_headers;
|
46 |
+
|
47 |
+
/** @var string raw response body */
|
48 |
+
protected $raw_response_body;
|
49 |
+
|
50 |
+
/** @var string response handler class name */
|
51 |
+
protected $response_handler;
|
52 |
+
|
53 |
+
/** @var API_Response|object response */
|
54 |
+
protected $response;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Perform the request and return the parsed response
|
58 |
+
*
|
59 |
+
* @since 3.0.0
|
60 |
+
*
|
61 |
+
* @param API_Request|object $request class instance which implements API_Request
|
62 |
+
* @return API_Response|object class instance which implements API_Response
|
63 |
+
* @throws API_Exception may be thrown in implementations
|
64 |
+
*/
|
65 |
+
protected function perform_request( $request ) {
|
66 |
+
|
67 |
+
// ensure API is in its default state
|
68 |
+
$this->reset_response();
|
69 |
+
|
70 |
+
// save the request object
|
71 |
+
$this->request = $request;
|
72 |
+
|
73 |
+
$start_time = microtime( true );
|
74 |
+
|
75 |
+
// if this API requires TLS v1.2, force it
|
76 |
+
if ( $this->require_tls_1_2() ) {
|
77 |
+
add_action( 'http_api_curl', array( $this, 'set_tls_1_2_request' ), 10, 3 );
|
78 |
+
}
|
79 |
+
|
80 |
+
// perform the request
|
81 |
+
$response = $this->do_remote_request( $this->get_request_uri(), $this->get_request_args() );
|
82 |
+
|
83 |
+
// calculate request duration
|
84 |
+
$this->request_duration = round( microtime( true ) - $start_time, 5 );
|
85 |
+
|
86 |
+
try {
|
87 |
+
|
88 |
+
// parse & validate response
|
89 |
+
$response = $this->handle_response( $response );
|
90 |
+
|
91 |
+
} catch ( \Exception $e ) {
|
92 |
+
|
93 |
+
// alert other actors that a request has been made
|
94 |
+
$this->broadcast_request();
|
95 |
+
|
96 |
+
throw $e;
|
97 |
+
}
|
98 |
+
|
99 |
+
return $response;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Simple wrapper for wp_remote_request() so child classes can override this
|
104 |
+
* and provide their own transport mechanism if needed, e.g. a custom
|
105 |
+
* cURL implementation
|
106 |
+
*
|
107 |
+
* @since 3.0.0
|
108 |
+
*
|
109 |
+
* @param string $request_uri
|
110 |
+
* @param string $request_args
|
111 |
+
* @return array|\WP_Error
|
112 |
+
*/
|
113 |
+
protected function do_remote_request( $request_uri, $request_args ) {
|
114 |
+
|
115 |
+
return wp_safe_remote_request( $request_uri, $request_args );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Handle and parse the response
|
120 |
+
*
|
121 |
+
* @since 3.0.0
|
122 |
+
* @param array|\WP_Error $response response data
|
123 |
+
* @throws \Exception network issues, timeouts, API errors, etc
|
124 |
+
* @return API_Request|object request class instance that implements API_Request
|
125 |
+
*/
|
126 |
+
protected function handle_response( $response ) {
|
127 |
+
|
128 |
+
// check for WP HTTP API specific errors (network timeout, etc)
|
129 |
+
if ( is_wp_error( $response ) ) {
|
130 |
+
throw new \Exception( $response->get_error_message(), (int) $response->get_error_code() );
|
131 |
+
}
|
132 |
+
|
133 |
+
// set response data
|
134 |
+
$this->response_code = wp_remote_retrieve_response_code( $response );
|
135 |
+
$this->response_message = wp_remote_retrieve_response_message( $response );
|
136 |
+
$this->raw_response_body = wp_remote_retrieve_body( $response );
|
137 |
+
|
138 |
+
$response_headers = wp_remote_retrieve_headers( $response );
|
139 |
+
|
140 |
+
// WP 4.6+ returns an object
|
141 |
+
if ( is_object( $response_headers ) ) {
|
142 |
+
$response_headers = $response_headers->getAll();
|
143 |
+
}
|
144 |
+
|
145 |
+
$this->response_headers = $response_headers;
|
146 |
+
|
147 |
+
// parse the response body and tie it to the request
|
148 |
+
$this->response = $this->get_parsed_response( $this->raw_response_body );
|
149 |
+
|
150 |
+
// fire do_action() so other actors can act on request/response data,
|
151 |
+
// primarily used for logging
|
152 |
+
$this->broadcast_request();
|
153 |
+
|
154 |
+
return $this->response;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Return the parsed response object for the request
|
159 |
+
*
|
160 |
+
* @since 3.0.0
|
161 |
+
* @param string $raw_response_body
|
162 |
+
* @return object|API_Request response class instance which implements API_Request
|
163 |
+
*/
|
164 |
+
protected function get_parsed_response( $raw_response_body ) {
|
165 |
+
|
166 |
+
$handler_class = $this->get_response_handler();
|
167 |
+
|
168 |
+
return new $handler_class( $raw_response_body );
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Alert other actors that a request has been performed. This is primarily used
|
173 |
+
* for request logging.
|
174 |
+
*
|
175 |
+
* @since 3.0.0
|
176 |
+
*/
|
177 |
+
protected function broadcast_request() {
|
178 |
+
|
179 |
+
$request_data = array(
|
180 |
+
'method' => $this->get_request_method(),
|
181 |
+
'uri' => $this->get_request_uri(),
|
182 |
+
'user-agent' => $this->get_request_user_agent(),
|
183 |
+
'headers' => $this->get_sanitized_request_headers(),
|
184 |
+
'body' => $this->get_sanitized_request_body(),
|
185 |
+
'duration' => $this->get_request_duration() . 's', // seconds
|
186 |
+
);
|
187 |
+
|
188 |
+
$response_data = array(
|
189 |
+
'code' => $this->get_response_code(),
|
190 |
+
'message' => $this->get_response_message(),
|
191 |
+
'headers' => $this->get_response_headers(),
|
192 |
+
'body' => $this->get_sanitized_response_body() ? $this->get_sanitized_response_body() : $this->get_raw_response_body(),
|
193 |
+
);
|
194 |
+
|
195 |
+
/**
|
196 |
+
* API Base Request Performed Action.
|
197 |
+
*
|
198 |
+
* Fired when an API request is performed via this base class. Plugins can
|
199 |
+
* hook into this to log request/response data.
|
200 |
+
*
|
201 |
+
* @since 3.0.0
|
202 |
+
* @param array $request_data {
|
203 |
+
* @type string $method request method, e.g. POST
|
204 |
+
* @type string $uri request URI
|
205 |
+
* @type string $user-agent
|
206 |
+
* @type string $headers request headers
|
207 |
+
* @type string $body request body
|
208 |
+
* @type string $duration in seconds
|
209 |
+
* }
|
210 |
+
* @param array $response data {
|
211 |
+
* @type string $code response HTTP code
|
212 |
+
* @type string $message response message
|
213 |
+
* @type string $headers response HTTP headers
|
214 |
+
* @type string $body response body
|
215 |
+
* }
|
216 |
+
* @param Base $this instance
|
217 |
+
*/
|
218 |
+
do_action( 'wc_' . $this->get_api_id() . '_api_request_performed', $request_data, $response_data, $this );
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Reset the API response members to their
|
223 |
+
*
|
224 |
+
* @since 3.0.0
|
225 |
+
*/
|
226 |
+
protected function reset_response() {
|
227 |
+
|
228 |
+
$this->response_code = null;
|
229 |
+
$this->response_message = null;
|
230 |
+
$this->response_headers = null;
|
231 |
+
$this->raw_response_body = null;
|
232 |
+
$this->response = null;
|
233 |
+
$this->request_duration = null;
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Get the request URI
|
238 |
+
*
|
239 |
+
* @since 3.0.0
|
240 |
+
* @return string
|
241 |
+
*/
|
242 |
+
protected function get_request_uri() {
|
243 |
+
|
244 |
+
$uri = $this->request_uri . $this->get_request_path();
|
245 |
+
|
246 |
+
// append any query params to the URL when necessary
|
247 |
+
$query = $this->get_request_query();
|
248 |
+
if ( $query ) {
|
249 |
+
|
250 |
+
$url_parts = parse_url( $uri );
|
251 |
+
|
252 |
+
// if the URL already has some query params, add to them
|
253 |
+
if ( ! empty( $url_parts['query'] ) ) {
|
254 |
+
$query = '&' . $query;
|
255 |
+
} else {
|
256 |
+
$query = '?' . $query;
|
257 |
+
}
|
258 |
+
|
259 |
+
$uri = untrailingslashit( $uri ) . $query;
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Request URI Filter.
|
264 |
+
*
|
265 |
+
* Allow actors to filter the request URI. Note that child classes can override
|
266 |
+
* this method, which means this filter may be invoked prior to the overridden
|
267 |
+
* method.
|
268 |
+
*
|
269 |
+
* @since 3.0.0
|
270 |
+
*
|
271 |
+
* @param string $uri current request URI
|
272 |
+
* @param Base class instance
|
273 |
+
*/
|
274 |
+
return apply_filters( 'wc_' . $this->get_api_id() . '_api_request_uri', $uri, $this );
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Gets the request path.
|
279 |
+
*
|
280 |
+
* @since 3.0.0
|
281 |
+
* @return string
|
282 |
+
*/
|
283 |
+
protected function get_request_path() {
|
284 |
+
|
285 |
+
return ( $this->get_request() ) ? $this->get_request()->get_path() : '';
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Gets the request URL query.
|
290 |
+
*
|
291 |
+
* @since 3.0.0
|
292 |
+
*
|
293 |
+
* @return string
|
294 |
+
*/
|
295 |
+
protected function get_request_query() {
|
296 |
+
|
297 |
+
$query = '';
|
298 |
+
$request = $this->get_request();
|
299 |
+
|
300 |
+
if ( $request && in_array( strtoupper( $this->get_request_method() ), array( 'GET', 'HEAD' ), true ) ) {
|
301 |
+
|
302 |
+
$params = $request->get_params();
|
303 |
+
|
304 |
+
if ( ! empty( $params ) ) {
|
305 |
+
$query = http_build_query( $params, '', '&' );
|
306 |
+
}
|
307 |
+
}
|
308 |
+
|
309 |
+
return $query;
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Get the request arguments in the format required by wp_remote_request()
|
314 |
+
*
|
315 |
+
* @since 3.0.0
|
316 |
+
*
|
317 |
+
* @return array
|
318 |
+
*/
|
319 |
+
protected function get_request_args() {
|
320 |
+
|
321 |
+
$args = array(
|
322 |
+
'method' => $this->get_request_method(),
|
323 |
+
'timeout' => MINUTE_IN_SECONDS,
|
324 |
+
'redirection' => 0,
|
325 |
+
'httpversion' => $this->get_request_http_version(),
|
326 |
+
'sslverify' => true,
|
327 |
+
'blocking' => true,
|
328 |
+
'user-agent' => $this->get_request_user_agent(),
|
329 |
+
'headers' => $this->get_request_headers(),
|
330 |
+
'body' => $this->get_request_body(),
|
331 |
+
'cookies' => array(),
|
332 |
+
);
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Request arguments.
|
336 |
+
*
|
337 |
+
* Allow other actors to filter the request arguments. Note that
|
338 |
+
* child classes can override this method, which means this filter may
|
339 |
+
* not be invoked, or may be invoked prior to the overridden method
|
340 |
+
*
|
341 |
+
* @since 3.0.0
|
342 |
+
* @param array $args request arguments
|
343 |
+
* @param Base class instance
|
344 |
+
*/
|
345 |
+
return apply_filters( 'wc_' . $this->get_api_id() . '_http_request_args', $args, $this );
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Get the request method, POST by default
|
350 |
+
*
|
351 |
+
* @since 3.0.0
|
352 |
+
* @return string
|
353 |
+
*/
|
354 |
+
protected function get_request_method() {
|
355 |
+
// if the request object specifies the method to use, use that, otherwise use the API default
|
356 |
+
return $this->get_request() && $this->get_request()->get_method() ? $this->get_request()->get_method() : $this->request_method;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Gets the request body.
|
361 |
+
*
|
362 |
+
* @since 3.0.0
|
363 |
+
* @return string
|
364 |
+
*/
|
365 |
+
protected function get_request_body() {
|
366 |
+
|
367 |
+
// GET & HEAD requests don't support a body
|
368 |
+
if ( in_array( strtoupper( $this->get_request_method() ), array( 'GET', 'HEAD' ), true ) ) {
|
369 |
+
return '';
|
370 |
+
}
|
371 |
+
|
372 |
+
return ( $this->get_request() && $this->get_request()->to_string() ) ? $this->get_request()->to_string() : '';
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Gets the sanitized request body, for logging.
|
377 |
+
*
|
378 |
+
* @since 3.0.0
|
379 |
+
* @return string
|
380 |
+
*/
|
381 |
+
protected function get_sanitized_request_body() {
|
382 |
+
|
383 |
+
// GET & HEAD requests don't support a body
|
384 |
+
if ( in_array( strtoupper( $this->get_request_method() ), array( 'GET', 'HEAD' ), true ) ) {
|
385 |
+
return '';
|
386 |
+
}
|
387 |
+
|
388 |
+
return ( $this->get_request() && $this->get_request()->to_string_safe() ) ? $this->get_request()->to_string_safe() : '';
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Get the request HTTP version, 1.1 by default
|
393 |
+
*
|
394 |
+
* @since 3.0.0
|
395 |
+
* @return string
|
396 |
+
*/
|
397 |
+
protected function get_request_http_version() {
|
398 |
+
|
399 |
+
return $this->request_http_version;
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* Get the request headers
|
404 |
+
*
|
405 |
+
* @since 3.0.0
|
406 |
+
* @return array
|
407 |
+
*/
|
408 |
+
protected function get_request_headers() {
|
409 |
+
return $this->request_headers;
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Get sanitized request headers suitable for logging, stripped of any
|
414 |
+
* confidential information
|
415 |
+
*
|
416 |
+
* The `Authorization` header is sanitized automatically.
|
417 |
+
*
|
418 |
+
* Child classes that implement any custom authorization headers should
|
419 |
+
* override this method to perform sanitization.
|
420 |
+
*
|
421 |
+
* @since 3.0.0
|
422 |
+
* @return array
|
423 |
+
*/
|
424 |
+
protected function get_sanitized_request_headers() {
|
425 |
+
|
426 |
+
$headers = $this->get_request_headers();
|
427 |
+
|
428 |
+
if ( ! empty( $headers['Authorization'] ) ) {
|
429 |
+
$headers['Authorization'] = str_repeat( '*', strlen( $headers['Authorization'] ) );
|
430 |
+
}
|
431 |
+
|
432 |
+
return $headers;
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Get the request user agent, defaults to:
|
437 |
+
*
|
438 |
+
* Dasherized-Plugin-Name/Plugin-Version (WooCommerce/WC-Version; WordPress/WP-Version)
|
439 |
+
*
|
440 |
+
* @since 3.0.0
|
441 |
+
* @return string
|
442 |
+
*/
|
443 |
+
protected function get_request_user_agent() {
|
444 |
+
|
445 |
+
return sprintf( '%s/%s (WooCommerce/%s; WordPress/%s)', str_replace( ' ', '-', $this->get_plugin()->get_plugin_name() ), $this->get_plugin()->get_version(), WC_VERSION, $GLOBALS['wp_version'] );
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Get the request duration in seconds, rounded to the 5th decimal place
|
450 |
+
*
|
451 |
+
* @since 3.0.0
|
452 |
+
* @return string
|
453 |
+
*/
|
454 |
+
protected function get_request_duration() {
|
455 |
+
return $this->request_duration;
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* Get the response handler class name
|
460 |
+
*
|
461 |
+
* @since 3.0.0
|
462 |
+
* @return string
|
463 |
+
*/
|
464 |
+
protected function get_response_handler() {
|
465 |
+
return $this->response_handler;
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Get the response code
|
470 |
+
*
|
471 |
+
* @since 3.0.0
|
472 |
+
* @return string
|
473 |
+
*/
|
474 |
+
protected function get_response_code() {
|
475 |
+
return $this->response_code;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Get the response message
|
480 |
+
*
|
481 |
+
* @since 3.0.0
|
482 |
+
* @return string
|
483 |
+
*/
|
484 |
+
protected function get_response_message() {
|
485 |
+
return $this->response_message;
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Get the response headers
|
490 |
+
*
|
491 |
+
* @since 3.0.0
|
492 |
+
* @return array
|
493 |
+
*/
|
494 |
+
protected function get_response_headers() {
|
495 |
+
return $this->response_headers;
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Get the raw response body, prior to any parsing or sanitization
|
500 |
+
*
|
501 |
+
* @since 3.0.0
|
502 |
+
* @return string
|
503 |
+
*/
|
504 |
+
protected function get_raw_response_body() {
|
505 |
+
return $this->raw_response_body;
|
506 |
+
}
|
507 |
+
|
508 |
+
/**
|
509 |
+
* Get the sanitized response body, provided by the response class
|
510 |
+
* to_string_safe() method
|
511 |
+
*
|
512 |
+
* @since 3.0.0
|
513 |
+
* @return string|null
|
514 |
+
*/
|
515 |
+
protected function get_sanitized_response_body() {
|
516 |
+
return is_callable( array( $this->get_response(), 'to_string_safe' ) ) ? $this->get_response()->to_string_safe() : null;
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Returns the most recent request object.
|
521 |
+
*
|
522 |
+
* @since 3.0.0
|
523 |
+
*
|
524 |
+
* @return API_Request|object the most recent request object
|
525 |
+
*/
|
526 |
+
public function get_request() {
|
527 |
+
|
528 |
+
return $this->request;
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Returns the most recent response object.
|
533 |
+
*
|
534 |
+
* @since 3.0.0
|
535 |
+
*
|
536 |
+
* @return API_Response|object the most recent response object
|
537 |
+
*/
|
538 |
+
public function get_response() {
|
539 |
+
|
540 |
+
return $this->response;
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Get the ID for the API, used primarily to namespace the action name
|
545 |
+
* for broadcasting requests
|
546 |
+
*
|
547 |
+
* @since 3.0.0
|
548 |
+
* @return string
|
549 |
+
*/
|
550 |
+
protected function get_api_id() {
|
551 |
+
|
552 |
+
return $this->get_plugin()->get_id();
|
553 |
+
}
|
554 |
+
|
555 |
+
/**
|
556 |
+
* Return a new request object
|
557 |
+
*
|
558 |
+
* Child classes must implement this to return an object that implements
|
559 |
+
* API_Request which should be used in the child class API methods
|
560 |
+
* to build the request. The returned API_Request should be passed
|
561 |
+
* to self::perform_request() by your concrete API methods
|
562 |
+
*
|
563 |
+
* @since 3.0.0
|
564 |
+
*
|
565 |
+
* @param array $args optional request arguments
|
566 |
+
* @return API_Request|object
|
567 |
+
*/
|
568 |
+
abstract protected function get_new_request( $args = array() );
|
569 |
+
|
570 |
+
/**
|
571 |
+
* Return the plugin class instance associated with this API
|
572 |
+
*
|
573 |
+
* Child classes must implement this to return their plugin class instance
|
574 |
+
*
|
575 |
+
* This is used for defining the plugin ID used in filter names, as well
|
576 |
+
* as the plugin name used for the default user agent.
|
577 |
+
*
|
578 |
+
* @since 3.0.0
|
579 |
+
*
|
580 |
+
* @return WooCommerce\Square\Framework\Plugin
|
581 |
+
*/
|
582 |
+
abstract protected function get_plugin();
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Set the response handler class name. This class will be instantiated
|
586 |
+
* to parse the response for the request.
|
587 |
+
*
|
588 |
+
* @since 3.0.0
|
589 |
+
*
|
590 |
+
* @param string $handler handle class name
|
591 |
+
*/
|
592 |
+
protected function set_response_handler( $handler ) {
|
593 |
+
$this->response_handler = $handler;
|
594 |
+
}
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Maybe force TLS v1.2 requests.
|
598 |
+
*
|
599 |
+
* @since 3.0.0
|
600 |
+
*
|
601 |
+
* @param resource $handle the cURL handle returned by curl_init() (passed by reference)
|
602 |
+
* @param array $r the HTTP request arguments
|
603 |
+
* @param $url string the request URL
|
604 |
+
*/
|
605 |
+
public function set_tls_1_2_request( $handle, $r, $url ) {
|
606 |
+
|
607 |
+
if ( ! Square_Helper::str_starts_with( $url, 'https://' ) ) {
|
608 |
+
return;
|
609 |
+
}
|
610 |
+
|
611 |
+
curl_setopt( $handle, CURLOPT_SSLVERSION, 6 );
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* Determine if TLS v1.2 is required for API requests.
|
616 |
+
*
|
617 |
+
* Subclasses should override this to return true if TLS v1.2 is required.
|
618 |
+
*
|
619 |
+
* @since 3.0.0
|
620 |
+
* @return bool
|
621 |
+
*/
|
622 |
+
public function require_tls_1_2() {
|
623 |
+
return false;
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Determines if TLS 1.2 is available.
|
628 |
+
*
|
629 |
+
* @since 3.0.0
|
630 |
+
*
|
631 |
+
* @return bool
|
632 |
+
*/
|
633 |
+
public function is_tls_1_2_available() {
|
634 |
+
|
635 |
+
// assume availability to avoid notices for unknown SSL types
|
636 |
+
$is_available = true;
|
637 |
+
|
638 |
+
// check the cURL version if installed
|
639 |
+
if ( is_callable( 'curl_version' ) ) {
|
640 |
+
|
641 |
+
$versions = curl_version();
|
642 |
+
|
643 |
+
// cURL 7.34.0 is considered the minimum version that supports TLS 1.2
|
644 |
+
if ( version_compare( $versions['version'], '7.34.0', '<' ) ) {
|
645 |
+
$is_available = false;
|
646 |
+
}
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* Filters whether TLS 1.2 is available.
|
651 |
+
*
|
652 |
+
* @since 3.0.0
|
653 |
+
*
|
654 |
+
* @param bool $is_available whether TLS 1.2 is available
|
655 |
+
* @param Base $api API class instance
|
656 |
+
*/
|
657 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_api_is_tls_1_2_available', $is_available, $this );
|
658 |
+
}
|
659 |
+
}
|
includes/Framework/Compatibility/Data_Compatibility.php
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\Compatibility;
|
4 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* WooCommerce data compatibility class.
|
10 |
+
*
|
11 |
+
* @since 3.0.0
|
12 |
+
*/
|
13 |
+
abstract class Data_Compatibility {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Gets an object property.
|
17 |
+
*
|
18 |
+
* @since 3.0.0
|
19 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
20 |
+
* @param string $prop the property name
|
21 |
+
* @param string $context if 'view' then the value will be filtered
|
22 |
+
* @param array $compat_props Compatibility properties.
|
23 |
+
* @return mixed
|
24 |
+
*/
|
25 |
+
public static function get_prop( $object, $prop, $context = 'edit', $compat_props = array() ) {
|
26 |
+
|
27 |
+
$value = '';
|
28 |
+
|
29 |
+
if ( is_callable( array( $object, "get_{$prop}" ) ) ) {
|
30 |
+
$value = $object->{"get_{$prop}"}( $context );
|
31 |
+
}
|
32 |
+
|
33 |
+
return $value;
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Sets an object's properties.
|
39 |
+
*
|
40 |
+
* Note that this does not save any data to the database.
|
41 |
+
*
|
42 |
+
* @since 3.0.0
|
43 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
44 |
+
* @param array $props the new properties as $key => $value
|
45 |
+
* @param array $compat_props Compatibility properties.
|
46 |
+
* @return \WC_Data
|
47 |
+
*/
|
48 |
+
public static function set_props( $object, $props, $compat_props = array() ) {
|
49 |
+
$object->set_props( $props );
|
50 |
+
|
51 |
+
return $object;
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Gets an object's stored meta value.
|
57 |
+
*
|
58 |
+
* @since 3.0.0
|
59 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
60 |
+
* @param string $key the meta key
|
61 |
+
* @param bool $single whether to get the meta as a single item. Defaults to `true`
|
62 |
+
* @param string $context if 'view' then the value will be filtered
|
63 |
+
* @return mixed
|
64 |
+
*/
|
65 |
+
public static function get_meta( $object, $key = '', $single = true, $context = 'edit' ) {
|
66 |
+
$value = $object->get_meta( $key, $single, $context );
|
67 |
+
|
68 |
+
return $value;
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Stores an object meta value.
|
74 |
+
*
|
75 |
+
* @since 3.0.0
|
76 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
77 |
+
* @param string $key the meta key
|
78 |
+
* @param string $value the meta value
|
79 |
+
* @param bool $unique Optional. Whether the meta should be unique.
|
80 |
+
*/
|
81 |
+
public static function add_meta_data( $object, $key, $value, $unique = false ) {
|
82 |
+
$object->add_meta_data( $key, $value, $unique );
|
83 |
+
$object->save_meta_data();
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Updates an object's stored meta value.
|
89 |
+
*
|
90 |
+
* @since 3.0.0
|
91 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
92 |
+
* @param string $key the meta key
|
93 |
+
* @param string $value the meta value
|
94 |
+
* @param int|string $meta_id Optional. The specific meta ID to update
|
95 |
+
*/
|
96 |
+
public static function update_meta_data( $object, $key, $value, $meta_id = '' ) {
|
97 |
+
$object->update_meta_data( $key, $value, $meta_id );
|
98 |
+
$object->save_meta_data();
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Deletes an object's stored meta value.
|
104 |
+
*
|
105 |
+
* @since 3.0.0
|
106 |
+
* @param \WC_Data $object the data object, likely \WC_Order or \WC_Product
|
107 |
+
* @param string $key the meta key
|
108 |
+
*/
|
109 |
+
public static function delete_meta_data( $object, $key ) {
|
110 |
+
$object->delete_meta_data( $key );
|
111 |
+
$object->save_meta_data();
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
includes/Framework/Compatibility/Order_Compatibility.php
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\Compatibility;
|
3 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* WooCommerce order compatibility class.
|
9 |
+
*
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
class Order_Compatibility extends Data_Compatibility {
|
13 |
+
|
14 |
+
/** @var array mapped compatibility properties, as `$new_prop => $old_prop` */
|
15 |
+
protected static $compat_props = array(
|
16 |
+
'date_completed' => 'completed_date',
|
17 |
+
'date_paid' => 'paid_date',
|
18 |
+
'date_modified' => 'modified_date',
|
19 |
+
'date_created' => 'order_date',
|
20 |
+
'customer_id' => 'customer_user',
|
21 |
+
'discount' => 'cart_discount',
|
22 |
+
'discount_tax' => 'cart_discount_tax',
|
23 |
+
'shipping_total' => 'total_shipping',
|
24 |
+
'type' => 'order_type',
|
25 |
+
'currency' => 'order_currency',
|
26 |
+
'version' => 'order_version',
|
27 |
+
);
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Gets an order date.
|
31 |
+
*
|
32 |
+
* This should only be used to retrieve WC core date properties.
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
*
|
36 |
+
* @param \WC_Order $order order object
|
37 |
+
* @param string $type type of date to get
|
38 |
+
* @param string $context if 'view' then the value will be filtered
|
39 |
+
*
|
40 |
+
* @return \WC_DateTime|null
|
41 |
+
*/
|
42 |
+
public static function get_date_prop( \WC_Order $order, $type, $context = 'edit' ) {
|
43 |
+
|
44 |
+
$date = null;
|
45 |
+
$prop = "date_{$type}";
|
46 |
+
$date = is_callable( array( $order, "get_{$prop}" ) ) ? $order->{"get_{$prop}"}( $context ) : null;
|
47 |
+
|
48 |
+
return $date;
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Gets an order property.
|
54 |
+
*
|
55 |
+
* @since 3.0.0
|
56 |
+
* @param \WC_Order $object the order object
|
57 |
+
* @param string $prop the property name
|
58 |
+
* @param string $context if 'view' then the value will be filtered
|
59 |
+
* @return mixed
|
60 |
+
*/
|
61 |
+
public static function get_prop( $object, $prop, $context = 'edit', $compat_props = array() ) {
|
62 |
+
|
63 |
+
// backport a few specific properties to pre-3.0
|
64 |
+
if ( Plugin_Compatibility::is_wc_version_lt_3_0() ) {
|
65 |
+
|
66 |
+
// convert the shipping_total prop for the edit context
|
67 |
+
if ( 'shipping_total' === $prop && 'view' !== $context ) {
|
68 |
+
|
69 |
+
$prop = 'order_shipping';
|
70 |
+
|
71 |
+
// get the post_parent and bail early
|
72 |
+
} elseif ( 'parent_id' === $prop ) {
|
73 |
+
|
74 |
+
return $object->post->post_parent;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
return parent::get_prop( $object, $prop, $context, self::$compat_props );
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Sets an order's properties.
|
84 |
+
*
|
85 |
+
* Note that this does not save any data to the database.
|
86 |
+
*
|
87 |
+
* @since 3.0.0
|
88 |
+
* @param \WC_Order $object the order object
|
89 |
+
* @param array $props the new properties as $key => $value
|
90 |
+
* @return \WC_Data|\WC_Order
|
91 |
+
*/
|
92 |
+
public static function set_props( $object, $props, $compat_props = array() ) {
|
93 |
+
|
94 |
+
return parent::set_props( $object, $props, self::$compat_props );
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Order item CRUD compatibility method to add a coupon to an order.
|
100 |
+
*
|
101 |
+
* @since 3.0.0
|
102 |
+
* @param \WC_Order $order the order object
|
103 |
+
* @param array $code the coupon code
|
104 |
+
* @param int $discount the discount amount.
|
105 |
+
* @param int $discount_tax the discount tax amount.
|
106 |
+
* @return int the order item ID
|
107 |
+
*/
|
108 |
+
public static function add_coupon( \WC_Order $order, $code = array(), $discount = 0, $discount_tax = 0 ) {
|
109 |
+
|
110 |
+
$item = new \WC_Order_Item_Coupon();
|
111 |
+
|
112 |
+
$item->set_props(
|
113 |
+
array(
|
114 |
+
'code' => $code,
|
115 |
+
'discount' => $discount,
|
116 |
+
'discount_tax' => $discount_tax,
|
117 |
+
'order_id' => $order->get_id(),
|
118 |
+
)
|
119 |
+
);
|
120 |
+
|
121 |
+
$item->save();
|
122 |
+
$order->add_item( $item );
|
123 |
+
|
124 |
+
return $item->get_id();
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Order item CRUD compatibility method to add a fee to an order.
|
130 |
+
*
|
131 |
+
* @since 3.0.0
|
132 |
+
* @param \WC_Order $order the order object
|
133 |
+
* @param object $fee the fee to add
|
134 |
+
* @return int the order item ID
|
135 |
+
*/
|
136 |
+
public static function add_fee( \WC_Order $order, $fee ) {
|
137 |
+
$item = new \WC_Order_Item_Fee();
|
138 |
+
|
139 |
+
$item->set_props(
|
140 |
+
array(
|
141 |
+
'name' => $fee->name,
|
142 |
+
'tax_class' => $fee->taxable ? $fee->tax_class : 0,
|
143 |
+
'total' => $fee->amount,
|
144 |
+
'total_tax' => $fee->tax,
|
145 |
+
'taxes' => array(
|
146 |
+
'total' => $fee->tax_data,
|
147 |
+
),
|
148 |
+
'order_id' => $order->get_id(),
|
149 |
+
)
|
150 |
+
);
|
151 |
+
|
152 |
+
$item->save();
|
153 |
+
$order->add_item( $item );
|
154 |
+
|
155 |
+
return $item->get_id();
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Order item CRUD compatibility method to add a shipping line to an order.
|
161 |
+
*
|
162 |
+
* @since 3.0.0
|
163 |
+
*
|
164 |
+
* @param \WC_Order $order order object
|
165 |
+
* @param \WC_Shipping_Rate $shipping_rate shipping rate to add
|
166 |
+
* @return int the order item ID
|
167 |
+
*/
|
168 |
+
public static function add_shipping( \WC_Order $order, $shipping_rate ) {
|
169 |
+
$item = new \WC_Order_Item_Shipping();
|
170 |
+
|
171 |
+
$item->set_props(
|
172 |
+
array(
|
173 |
+
'method_title' => $shipping_rate->label,
|
174 |
+
'method_id' => $shipping_rate->id,
|
175 |
+
'total' => wc_format_decimal( $shipping_rate->cost ),
|
176 |
+
'taxes' => $shipping_rate->taxes,
|
177 |
+
'order_id' => $order->get_id(),
|
178 |
+
)
|
179 |
+
);
|
180 |
+
|
181 |
+
foreach ( $shipping_rate->get_meta_data() as $key => $value ) {
|
182 |
+
$item->add_meta_data( $key, $value, true );
|
183 |
+
}
|
184 |
+
|
185 |
+
$item->save();
|
186 |
+
$order->add_item( $item );
|
187 |
+
|
188 |
+
return $item->get_id();
|
189 |
+
}
|
190 |
+
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Order item CRUD compatibility method to add a tax line to an order.
|
194 |
+
*
|
195 |
+
* @since 3.0.0
|
196 |
+
*
|
197 |
+
* @param \WC_Order $order order object
|
198 |
+
* @param int $tax_rate_id tax rate ID
|
199 |
+
* @param float $tax_amount cart tax amount
|
200 |
+
* @param float $shipping_tax_amount shipping tax amount
|
201 |
+
* @return int order item ID
|
202 |
+
*/
|
203 |
+
public static function add_tax( \WC_Order $order, $tax_rate_id, $tax_amount = 0, $shipping_tax_amount = 0 ) {
|
204 |
+
$item = new \WC_Order_Item_Tax();
|
205 |
+
|
206 |
+
$item->set_props(
|
207 |
+
array(
|
208 |
+
'rate_id' => $tax_rate_id,
|
209 |
+
'tax_total' => $tax_amount,
|
210 |
+
'shipping_tax_total' => $shipping_tax_amount,
|
211 |
+
)
|
212 |
+
);
|
213 |
+
|
214 |
+
$item->set_rate( $tax_rate_id );
|
215 |
+
$item->set_order_id( $order->get_id() );
|
216 |
+
$item->save();
|
217 |
+
|
218 |
+
$order->add_item( $item );
|
219 |
+
|
220 |
+
return $item->get_id();
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Determines if an order has an available shipping address.
|
225 |
+
*
|
226 |
+
* WooCommerce 3.0+ no longer fills the shipping address with the billing if
|
227 |
+
* a shipping address was never set by the customer at checkout, as is the
|
228 |
+
* case with virtual orders. This method is helpful for gateways that may
|
229 |
+
* reject such transactions with blank shipping information.
|
230 |
+
*
|
231 |
+
* TODO: Remove when WC 3.0.4 can be required {CW 2017-04-17}
|
232 |
+
*
|
233 |
+
* @since 3.0.0
|
234 |
+
*
|
235 |
+
* @param \WC_Order $order order object
|
236 |
+
*
|
237 |
+
* @return bool
|
238 |
+
*/
|
239 |
+
public static function has_shipping_address( \WC_Order $order ) {
|
240 |
+
|
241 |
+
return self::get_prop( $order, 'shipping_address_1' ) || self::get_prop( $order, 'shipping_address_2' );
|
242 |
+
}
|
243 |
+
}
|
includes/Framework/Lifecycle.php
ADDED
@@ -0,0 +1,550 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework;
|
4 |
+
|
5 |
+
use WooCommerce;
|
6 |
+
|
7 |
+
defined( 'ABSPATH' ) or exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Plugin lifecycle handler.
|
11 |
+
*
|
12 |
+
* Registers and displays milestone notice prompts and eventually the plugin
|
13 |
+
* install, upgrade, activation, and deactivation routines.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Lifecycle {
|
18 |
+
|
19 |
+
|
20 |
+
/** @var array the version numbers that have an upgrade routine */
|
21 |
+
protected $upgrade_versions = array();
|
22 |
+
|
23 |
+
/** @var string minimum milestone version */
|
24 |
+
private $milestone_version;
|
25 |
+
|
26 |
+
/** @var Plugin plugin instance */
|
27 |
+
private $plugin;
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Constructs the class.
|
32 |
+
*
|
33 |
+
* @since 3.0.0
|
34 |
+
*
|
35 |
+
* @param Plugin $plugin plugin instance
|
36 |
+
*/
|
37 |
+
public function __construct( WooCommerce\Square\Framework\Plugin $plugin ) {
|
38 |
+
|
39 |
+
$this->plugin = $plugin;
|
40 |
+
|
41 |
+
$this->add_hooks();
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Adds the action & filter hooks.
|
47 |
+
*
|
48 |
+
* @since 3.0.0
|
49 |
+
*/
|
50 |
+
protected function add_hooks() {
|
51 |
+
|
52 |
+
// handle activation
|
53 |
+
add_action( 'admin_init', array( $this, 'handle_activation' ) );
|
54 |
+
|
55 |
+
// handle deactivation
|
56 |
+
add_action( 'deactivate_' . $this->get_plugin()->get_plugin_file(), array( $this, 'handle_deactivation' ) );
|
57 |
+
|
58 |
+
if ( is_admin() && ! wp_doing_ajax() ) {
|
59 |
+
|
60 |
+
// initialize the plugin lifecycle
|
61 |
+
add_action( 'wp_loaded', array( $this, 'init' ) );
|
62 |
+
|
63 |
+
// add the admin notices
|
64 |
+
add_action( 'init', array( $this, 'add_admin_notices' ) );
|
65 |
+
}
|
66 |
+
|
67 |
+
// catch any milestones triggered by action
|
68 |
+
add_action( 'wc_' . $this->get_plugin()->get_id() . '_milestone_reached', array( $this, 'trigger_milestone' ), 10, 3 );
|
69 |
+
}
|
70 |
+
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Initializes the plugin lifecycle.
|
74 |
+
*
|
75 |
+
* @since 3.0.0
|
76 |
+
*/
|
77 |
+
public function init() {
|
78 |
+
|
79 |
+
// potentially handle a new activation
|
80 |
+
$this->handle_activation();
|
81 |
+
|
82 |
+
$installed_version = $this->get_installed_version();
|
83 |
+
$plugin_version = $this->get_plugin()->get_version();
|
84 |
+
|
85 |
+
// installed version lower than plugin version?
|
86 |
+
if ( version_compare( $installed_version, $plugin_version, '<' ) ) {
|
87 |
+
|
88 |
+
if ( ! $installed_version ) {
|
89 |
+
|
90 |
+
// store the upgrade event regardless if there was a routine for it
|
91 |
+
$this->store_event( 'install' );
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Fires after the plugin has been installed.
|
95 |
+
*
|
96 |
+
* @since 3.0.0
|
97 |
+
*/
|
98 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_installed' );
|
99 |
+
|
100 |
+
} else {
|
101 |
+
|
102 |
+
$this->upgrade( $installed_version );
|
103 |
+
|
104 |
+
// store the upgrade event regardless if there was a routine for it
|
105 |
+
$this->add_upgrade_event( $installed_version );
|
106 |
+
|
107 |
+
// if the plugin never had any previous milestones, consider them all reached so their notices aren't displayed
|
108 |
+
if ( ! $this->get_milestone_version() ) {
|
109 |
+
$this->set_milestone_version( $plugin_version );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Fires after the plugin has been updated.
|
114 |
+
*
|
115 |
+
* @since 3.0.0
|
116 |
+
*
|
117 |
+
* @param string $installed_version previously installed version
|
118 |
+
*/
|
119 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_updated', $installed_version );
|
120 |
+
}
|
121 |
+
|
122 |
+
// new version number
|
123 |
+
$this->set_installed_version( $plugin_version );
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Triggers plugin activation.
|
130 |
+
*
|
131 |
+
* We don't use register_activation_hook() as that can't be called inside
|
132 |
+
* the 'plugins_loaded' action. Instead, we rely on setting to track the
|
133 |
+
* plugin's activation status.
|
134 |
+
*
|
135 |
+
* @internal
|
136 |
+
*
|
137 |
+
* @link https://developer.wordpress.org/reference/functions/register_activation_hook/#comment-2100
|
138 |
+
*
|
139 |
+
* @since 3.0.0
|
140 |
+
*/
|
141 |
+
public function handle_activation() {
|
142 |
+
|
143 |
+
if ( ! get_option( 'wc_' . $this->get_plugin()->get_id() . '_is_active', false ) ) {
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Fires when the plugin is activated.
|
147 |
+
*
|
148 |
+
* @since 3.0.0
|
149 |
+
*/
|
150 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_activated' );
|
151 |
+
|
152 |
+
update_option( 'wc_' . $this->get_plugin()->get_id() . '_is_active', 'yes' );
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Triggers plugin deactivation.
|
159 |
+
*
|
160 |
+
* @internal
|
161 |
+
*
|
162 |
+
* @since 3.0.0
|
163 |
+
*/
|
164 |
+
public function handle_deactivation() {
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Fires when the plugin is deactivated.
|
168 |
+
*
|
169 |
+
* @since 3.0.0
|
170 |
+
*/
|
171 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_deactivated' );
|
172 |
+
|
173 |
+
delete_option( 'wc_' . $this->get_plugin()->get_id() . '_is_active' );
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Helper method to install default settings for a plugin.
|
178 |
+
*
|
179 |
+
* @since 3.0.0
|
180 |
+
*
|
181 |
+
* @param array $settings settings in format required by WC_Admin_Settings
|
182 |
+
*/
|
183 |
+
public function install_default_settings( array $settings ) {
|
184 |
+
|
185 |
+
foreach ( $settings as $setting ) {
|
186 |
+
|
187 |
+
if ( isset( $setting['id'], $setting['default'] ) ) {
|
188 |
+
update_option( $setting['id'], $setting['default'] );
|
189 |
+
}
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Performs any upgrade tasks based on the provided installed version.
|
195 |
+
*
|
196 |
+
* @since 3.0.0
|
197 |
+
*
|
198 |
+
* @param string $installed_version installed version
|
199 |
+
*/
|
200 |
+
protected function upgrade( $installed_version ) {
|
201 |
+
|
202 |
+
foreach ( $this->upgrade_versions as $upgrade_version ) {
|
203 |
+
|
204 |
+
$upgrade_method = 'upgrade_to_' . str_replace( array( '.', '-' ), '_', $upgrade_version );
|
205 |
+
|
206 |
+
if ( version_compare( $installed_version, $upgrade_version, '<' ) && is_callable( array( $this, $upgrade_method ) ) ) {
|
207 |
+
|
208 |
+
$this->get_plugin()->log( sprintf( "Starting upgrade to v%s", $upgrade_version ) );
|
209 |
+
|
210 |
+
$this->$upgrade_method( $installed_version );
|
211 |
+
|
212 |
+
$this->get_plugin()->log( sprintf( "Upgrade to v%s complete.", $upgrade_version ) );
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Adds any lifecycle admin notices.
|
220 |
+
*
|
221 |
+
* @since 3.0.0
|
222 |
+
*/
|
223 |
+
public function add_admin_notices() {
|
224 |
+
|
225 |
+
// display any milestone notices
|
226 |
+
foreach ( $this->get_milestone_messages() as $id => $message ) {
|
227 |
+
|
228 |
+
// bail if this notice was already dismissed
|
229 |
+
if ( ! $this->get_plugin()->get_admin_notice_handler()->should_display_notice( $id ) ) {
|
230 |
+
continue;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Filters a milestone notice message.
|
235 |
+
*
|
236 |
+
* @since 3.0.0
|
237 |
+
*
|
238 |
+
* @param string $message message text to be used for the milestone notice
|
239 |
+
* @param string $id milestone ID
|
240 |
+
*/
|
241 |
+
$message = apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_milestone_message', $this->generate_milestone_notice_message( $message ), $id );
|
242 |
+
|
243 |
+
if ( $message ) {
|
244 |
+
|
245 |
+
$this->get_plugin()->get_admin_notice_handler()->add_admin_notice( $message, $id, array(
|
246 |
+
'always_show_on_settings' => false,
|
247 |
+
) );
|
248 |
+
|
249 |
+
// only display one notice at a time
|
250 |
+
break;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
|
256 |
+
/** Milestone Methods *****************************************************/
|
257 |
+
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Triggers a milestone.
|
261 |
+
*
|
262 |
+
* This will only be triggered if the install's "milestone version" is lower
|
263 |
+
* than $since. Plugins can specify $since as the version at which a
|
264 |
+
* milestone's feature was added. This prevents existing installs from
|
265 |
+
* triggering notices for milestones that have long passed, like a payment
|
266 |
+
* gateway's first successful payment. Omitting $since will assume the
|
267 |
+
* milestone has always existed and should only trigger for fresh installs.
|
268 |
+
*
|
269 |
+
* @since 3.0.0
|
270 |
+
*
|
271 |
+
* @param string $id milestone ID
|
272 |
+
* @param string $message message to display to the user
|
273 |
+
* @param string $since the version since this milestone has existed in the plugin
|
274 |
+
* @return bool
|
275 |
+
*/
|
276 |
+
public function trigger_milestone( $id, $message, $since = '1.0.0' ) {
|
277 |
+
|
278 |
+
// if the plugin was had milestones before this milestone was added, don't trigger it
|
279 |
+
if ( version_compare( $this->get_milestone_version(), $since, '>' ) ) {
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
|
283 |
+
return $this->register_milestone_message( $id, $message );
|
284 |
+
}
|
285 |
+
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Generates a milestone notice message.
|
289 |
+
*
|
290 |
+
* @since 3.0.0
|
291 |
+
*
|
292 |
+
* @param string $custom_message custom text that notes what milestone was completed.
|
293 |
+
* @return string
|
294 |
+
*/
|
295 |
+
protected function generate_milestone_notice_message( $custom_message ) {
|
296 |
+
|
297 |
+
$message = '';
|
298 |
+
|
299 |
+
if ( $this->get_plugin()->get_reviews_url() ) {
|
300 |
+
|
301 |
+
// to be prepended at random to each milestone notice
|
302 |
+
$exclamations = array(
|
303 |
+
__( 'Awesome', 'woocommerce-square' ),
|
304 |
+
__( 'Fantastic', 'woocommerce-square' ),
|
305 |
+
__( 'Cowabunga', 'woocommerce-square' ),
|
306 |
+
__( 'Congratulations', 'woocommerce-square' ),
|
307 |
+
__( 'Hot dog', 'woocommerce-square' ),
|
308 |
+
);
|
309 |
+
|
310 |
+
$message = $exclamations[ array_rand( $exclamations ) ] . ', ' . esc_html( $custom_message ) . ' ';
|
311 |
+
|
312 |
+
$message .= sprintf(
|
313 |
+
/* translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a> tag, %4$s - <a> tag, %5$s - </a> tag */
|
314 |
+
__( 'Are you having a great experience with %1$s so far? Please consider %2$sleaving a review%3$s! If things aren\'t going quite as expected, we\'re happy to help -- please %4$sreach out to our support team%5$s.', 'woocommerce-square' ),
|
315 |
+
'<strong>' . esc_html( $this->get_plugin()->get_plugin_name() ) . '</strong>',
|
316 |
+
'<a href="' . esc_url( $this->get_plugin()->get_reviews_url() ) . '">', '</a>',
|
317 |
+
'<a href="' . esc_url( $this->get_plugin()->get_support_url() ) . '">', '</a>'
|
318 |
+
);
|
319 |
+
}
|
320 |
+
|
321 |
+
return $message;
|
322 |
+
}
|
323 |
+
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Registers a milestone message to be displayed in the admin.
|
327 |
+
*
|
328 |
+
* @since 3.0.0
|
329 |
+
* @see Lifecycle::generate_milestone_notice_message()
|
330 |
+
*
|
331 |
+
* @param string $id milestone ID
|
332 |
+
* @param string $message message to display to the user
|
333 |
+
* @return bool whether the message was successfully registered
|
334 |
+
*/
|
335 |
+
public function register_milestone_message( $id, $message ) {
|
336 |
+
|
337 |
+
$milestone_messages = $this->get_milestone_messages();
|
338 |
+
$dismissed_notices = array_keys( $this->get_plugin()->get_admin_notice_handler()->get_dismissed_notices() );
|
339 |
+
|
340 |
+
// get the total number of dismissed milestone messages
|
341 |
+
$dismissed_milestone_messages = array_intersect( array_keys( $milestone_messages ), $dismissed_notices );
|
342 |
+
|
343 |
+
// if the user has dismissed more than three milestone messages already, don't add any more
|
344 |
+
if ( count( $dismissed_milestone_messages ) > 3 ) {
|
345 |
+
return false;
|
346 |
+
}
|
347 |
+
|
348 |
+
$milestone_messages[ $id ] = $message;
|
349 |
+
|
350 |
+
return update_option( 'wc_' . $this->get_plugin()->get_id() . '_milestone_messages', $milestone_messages );
|
351 |
+
}
|
352 |
+
|
353 |
+
|
354 |
+
/** Event history methods *****************************************************************************************/
|
355 |
+
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Adds an upgrade lifecycle event.
|
359 |
+
*
|
360 |
+
* @since 3.0.0
|
361 |
+
*
|
362 |
+
* @param string $from_version version upgrading from
|
363 |
+
* @param array $data extra data to add
|
364 |
+
* @return false|int
|
365 |
+
*/
|
366 |
+
public function add_upgrade_event( $from_version, array $data = array() ) {
|
367 |
+
|
368 |
+
$data = array_merge( array(
|
369 |
+
'from_version' => $from_version,
|
370 |
+
), $data );
|
371 |
+
|
372 |
+
return $this->store_event( 'upgrade', $data );
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Stores a lifecycle event.
|
377 |
+
*
|
378 |
+
* This can be used to log installs, upgrades, etc...
|
379 |
+
*
|
380 |
+
* Uses a direct database query to avoid cache issues.
|
381 |
+
*
|
382 |
+
* @since 3.0.0
|
383 |
+
*
|
384 |
+
* @param string $name lifecycle event name
|
385 |
+
* @param array $data any extra data to store
|
386 |
+
* @return false|int
|
387 |
+
*/
|
388 |
+
public function store_event( $name, array $data = array() ) {
|
389 |
+
global $wpdb;
|
390 |
+
|
391 |
+
$history = $this->get_event_history();
|
392 |
+
|
393 |
+
$event = array(
|
394 |
+
'name' => wc_clean( $name ),
|
395 |
+
'time' => (int) current_time( 'timestamp' ),
|
396 |
+
'version' => wc_clean( $this->get_plugin()->get_version() ),
|
397 |
+
);
|
398 |
+
|
399 |
+
if ( ! empty( $data ) ) {
|
400 |
+
$event['data'] = wc_clean( $data );
|
401 |
+
}
|
402 |
+
|
403 |
+
array_unshift( $history, $event );
|
404 |
+
|
405 |
+
// limit to the last 30 events
|
406 |
+
$history = array_slice( $history, 0, 29 );
|
407 |
+
|
408 |
+
return $wpdb->replace(
|
409 |
+
$wpdb->options,
|
410 |
+
array(
|
411 |
+
'option_name' => $this->get_event_history_option_name(),
|
412 |
+
'option_value' => wp_json_encode( $history ),
|
413 |
+
'autoload' => 'no',
|
414 |
+
),
|
415 |
+
array(
|
416 |
+
'%s',
|
417 |
+
'%s',
|
418 |
+
)
|
419 |
+
);
|
420 |
+
}
|
421 |
+
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Gets the lifecycle event history.
|
425 |
+
*
|
426 |
+
* The last 30 events are stored, with the latest first.
|
427 |
+
*
|
428 |
+
* @since 3.0.0
|
429 |
+
*
|
430 |
+
* @return array
|
431 |
+
*/
|
432 |
+
public function get_event_history() {
|
433 |
+
global $wpdb;
|
434 |
+
|
435 |
+
$history = array();
|
436 |
+
|
437 |
+
$results = $wpdb->get_var( $wpdb->prepare( "
|
438 |
+
SELECT option_value
|
439 |
+
FROM {$wpdb->options}
|
440 |
+
WHERE option_name = %s
|
441 |
+
", $this->get_event_history_option_name() ) );
|
442 |
+
|
443 |
+
if ( $results ) {
|
444 |
+
$history = json_decode( $results, true );
|
445 |
+
}
|
446 |
+
|
447 |
+
return is_array( $history ) ? $history : array();
|
448 |
+
}
|
449 |
+
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Gets the event history option name.
|
453 |
+
*
|
454 |
+
* @since 3.0.0
|
455 |
+
*
|
456 |
+
* @return string
|
457 |
+
*/
|
458 |
+
protected function get_event_history_option_name() {
|
459 |
+
|
460 |
+
return 'wc_' . $this->get_plugin()->get_id() . '_lifecycle_events';
|
461 |
+
}
|
462 |
+
|
463 |
+
|
464 |
+
/** Utility Methods *******************************************************/
|
465 |
+
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Gets the registered milestone messages.
|
469 |
+
*
|
470 |
+
* @since 3.0.0
|
471 |
+
*
|
472 |
+
* @return array
|
473 |
+
*/
|
474 |
+
protected function get_milestone_messages() {
|
475 |
+
|
476 |
+
return get_option( 'wc_' . $this->get_plugin()->get_id() . '_milestone_messages', array() );
|
477 |
+
}
|
478 |
+
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Sets the milestone version.
|
482 |
+
*
|
483 |
+
* @since 3.0.0
|
484 |
+
*
|
485 |
+
* @param string $version plugin version
|
486 |
+
* @return bool
|
487 |
+
*/
|
488 |
+
public function set_milestone_version( $version ) {
|
489 |
+
|
490 |
+
$this->milestone_version = $version;
|
491 |
+
|
492 |
+
return update_option( 'wc_' . $this->get_plugin()->get_id() . '_milestone_version', $version );
|
493 |
+
}
|
494 |
+
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Gets the milestone version.
|
498 |
+
*
|
499 |
+
* @since 3.0.0
|
500 |
+
*
|
501 |
+
* @return string
|
502 |
+
*/
|
503 |
+
public function get_milestone_version() {
|
504 |
+
|
505 |
+
if ( ! $this->milestone_version ) {
|
506 |
+
$this->milestone_version = get_option( 'wc_' . $this->get_plugin()->get_id() . '_milestone_version', '' );
|
507 |
+
}
|
508 |
+
|
509 |
+
return $this->milestone_version;
|
510 |
+
}
|
511 |
+
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Gets the currently installed plugin version.
|
515 |
+
*
|
516 |
+
* @since 3.0.0
|
517 |
+
*
|
518 |
+
* @return string
|
519 |
+
*/
|
520 |
+
protected function get_installed_version() {
|
521 |
+
|
522 |
+
return get_option( $this->get_plugin()->get_plugin_version_name() );
|
523 |
+
}
|
524 |
+
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Sets the installed plugin version.
|
528 |
+
*
|
529 |
+
* @since 3.0.0
|
530 |
+
*
|
531 |
+
* @param string $version version to set
|
532 |
+
*/
|
533 |
+
protected function set_installed_version( $version ) {
|
534 |
+
|
535 |
+
update_option( $this->get_plugin()->get_plugin_version_name(), $version );
|
536 |
+
}
|
537 |
+
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Gets the plugin instance.
|
541 |
+
*
|
542 |
+
* @since 3.0.0
|
543 |
+
*
|
544 |
+
* @return Plugin
|
545 |
+
*/
|
546 |
+
protected function get_plugin() {
|
547 |
+
|
548 |
+
return $this->plugin;
|
549 |
+
}
|
550 |
+
}
|
includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Order.php
ADDED
@@ -0,0 +1,434 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Admin;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Plugin;
|
5 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Plugin;
|
8 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) or exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Handle the admin order screens.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Payment_Gateway_Admin_Order {
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Payment_Gateway_Plugin the plugin instance **/
|
21 |
+
protected $plugin;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Constructs the class.
|
26 |
+
*
|
27 |
+
* @since 3.0.0
|
28 |
+
*
|
29 |
+
* @param Payment_Gateway_Plugin The plugin instance
|
30 |
+
*/
|
31 |
+
public function __construct( Payment_Gateway_Plugin $plugin ) {
|
32 |
+
|
33 |
+
$this->plugin = $plugin;
|
34 |
+
|
35 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
36 |
+
|
37 |
+
// capture feature
|
38 |
+
if ( $this->get_plugin()->supports_capture_charge() ) {
|
39 |
+
|
40 |
+
add_action( 'woocommerce_order_item_add_action_buttons', array( $this, 'add_capture_button' ) );
|
41 |
+
|
42 |
+
add_action( 'wp_ajax_wc_' . $this->get_plugin()->get_id() . '_capture_charge', array( $this, 'ajax_process_capture' ) );
|
43 |
+
|
44 |
+
// bulk capture order action
|
45 |
+
add_action( 'admin_footer-edit.php', array( $this, 'maybe_add_capture_charge_bulk_order_action' ) );
|
46 |
+
add_action( 'load-edit.php', array( $this, 'process_capture_charge_bulk_order_action' ) );
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Enqueues the scripts and styles.
|
53 |
+
*
|
54 |
+
* @internal
|
55 |
+
*
|
56 |
+
* @since 3.0.0
|
57 |
+
*
|
58 |
+
* @param string $hook_suffix page hook suffix
|
59 |
+
*/
|
60 |
+
public function enqueue_scripts( $hook_suffix ) {
|
61 |
+
|
62 |
+
// Order screen assets
|
63 |
+
if ( 'shop_order' === get_post_type() ) {
|
64 |
+
|
65 |
+
// Edit Order screen assets
|
66 |
+
if ( 'post.php' === $hook_suffix ) {
|
67 |
+
|
68 |
+
$order = wc_get_order( Square_Helper::get_request( 'post' ) );
|
69 |
+
|
70 |
+
if ( ! $order ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
// bail if the order payment method doesn't belong to this plugin
|
75 |
+
if ( ! $this->get_order_gateway( $order ) ) {
|
76 |
+
return;
|
77 |
+
}
|
78 |
+
|
79 |
+
$this->enqueue_edit_order_assets( $order );
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Enqueues the assets for the Edit Order screen.
|
87 |
+
*
|
88 |
+
* @since 3.0.0
|
89 |
+
*
|
90 |
+
* @param \WC_Order $order order object
|
91 |
+
*/
|
92 |
+
protected function enqueue_edit_order_assets( \WC_Order $order ) {
|
93 |
+
|
94 |
+
wp_enqueue_script( 'payment-gateway-admin-order', $this->get_plugin()->get_plugin_url() . '/assets/js/admin/wc-square-payment-gateway-admin-order.min.js', array( 'jquery' ), Plugin::VERSION, true );
|
95 |
+
|
96 |
+
wp_localize_script( 'payment-gateway-admin-order', 'sv_wc_payment_gateway_admin_order', array(
|
97 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
98 |
+
'gateway_id' => Order_Compatibility::get_prop( $order, 'payment_method' ),
|
99 |
+
'order_id' => Order_Compatibility::get_prop( $order, 'id' ),
|
100 |
+
'capture_ays' => esc_html__( 'Are you sure you wish to process this capture? The action cannot be undone.', 'woocommerce-square' ),
|
101 |
+
'capture_action' => 'wc_' . $this->get_plugin()->get_id() . '_capture_charge',
|
102 |
+
'capture_nonce' => wp_create_nonce( 'wc_' . $this->get_plugin()->get_id() . '_capture_charge' ),
|
103 |
+
'capture_error' => esc_html__( 'Something went wrong, and the capture could no be completed. Please try again.', 'woocommerce-square' ),
|
104 |
+
) );
|
105 |
+
|
106 |
+
wp_enqueue_style( 'payment-gateway-admin-order', $this->get_plugin()->get_plugin_url() . '/assets/css/admin/wc-square-payment-gateway-admin-order.min.css', Plugin::VERSION );
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
/** Capture Charge Feature ******************************************************/
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Adds 'Capture charge' to the Orders screen bulk action select.
|
115 |
+
*
|
116 |
+
* @since 3.0.0
|
117 |
+
*/
|
118 |
+
public function maybe_add_capture_charge_bulk_order_action() {
|
119 |
+
global $post_type, $post_status;
|
120 |
+
|
121 |
+
if ( ! current_user_can( 'edit_shop_orders' ) ) {
|
122 |
+
return;
|
123 |
+
}
|
124 |
+
|
125 |
+
if ( $post_type === 'shop_order' && $post_status !== 'trash' ) {
|
126 |
+
|
127 |
+
$can_capture_charge = false;
|
128 |
+
|
129 |
+
// ensure at least one gateway supports capturing charge
|
130 |
+
foreach ( $this->get_plugin()->get_gateways() as $gateway ) {
|
131 |
+
|
132 |
+
// ensure that it supports captures
|
133 |
+
if ( $gateway->supports_credit_card_capture() ) {
|
134 |
+
|
135 |
+
$can_capture_charge = true;
|
136 |
+
break;
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
if ( $can_capture_charge ) {
|
141 |
+
|
142 |
+
?>
|
143 |
+
<script type="text/javascript">
|
144 |
+
jQuery( document ).ready( function ( $ ) {
|
145 |
+
if ( 0 == $( 'select[name^=action] option[value=wc_capture_charge]' ).size() ) {
|
146 |
+
$( 'select[name^=action]' ).append(
|
147 |
+
$( '<option>' ).val( '<?php echo esc_js( 'wc_capture_charge' ); ?>' ).text( '<?php esc_html_e( 'Capture Charge', 'woocommerce-square' ); ?>' )
|
148 |
+
);
|
149 |
+
}
|
150 |
+
});
|
151 |
+
</script>
|
152 |
+
<?php
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Processes the 'Capture Charge' custom bulk action.
|
160 |
+
*
|
161 |
+
* @since 3.0.0
|
162 |
+
*/
|
163 |
+
public function process_capture_charge_bulk_order_action() {
|
164 |
+
global $typenow;
|
165 |
+
|
166 |
+
if ( 'shop_order' === $typenow ) {
|
167 |
+
|
168 |
+
// get the action
|
169 |
+
$wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
|
170 |
+
$action = $wp_list_table->current_action();
|
171 |
+
|
172 |
+
// bail if not processing a capture
|
173 |
+
if ( 'wc_capture_charge' !== $action ) {
|
174 |
+
return;
|
175 |
+
}
|
176 |
+
|
177 |
+
if ( ! current_user_can( 'edit_shop_orders' ) ) {
|
178 |
+
return;
|
179 |
+
}
|
180 |
+
|
181 |
+
// security check
|
182 |
+
check_admin_referer( 'bulk-posts' );
|
183 |
+
|
184 |
+
// make sure order IDs are submitted
|
185 |
+
if ( isset( $_REQUEST['post'] ) ) {
|
186 |
+
$order_ids = array_map( 'absint', $_REQUEST['post'] );
|
187 |
+
}
|
188 |
+
|
189 |
+
// return if there are no orders to export
|
190 |
+
if ( empty( $order_ids ) ) {
|
191 |
+
return;
|
192 |
+
}
|
193 |
+
|
194 |
+
// give ourselves an unlimited timeout if possible
|
195 |
+
@set_time_limit( 0 );
|
196 |
+
|
197 |
+
foreach ( $order_ids as $order_id ) {
|
198 |
+
|
199 |
+
$order = wc_get_order( $order_id );
|
200 |
+
|
201 |
+
if ( $order && ( $gateway = $this->get_order_gateway( $order ) ) ) {
|
202 |
+
$gateway->get_capture_handler()->maybe_perform_capture( $order );
|
203 |
+
}
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Adds the capture charge button to the order UI.
|
210 |
+
*
|
211 |
+
* @internal
|
212 |
+
*
|
213 |
+
* @since 3.0.0
|
214 |
+
*
|
215 |
+
* @param \WC_Order $order order object
|
216 |
+
*/
|
217 |
+
public function add_capture_button( $order ) {
|
218 |
+
|
219 |
+
// only display the button for core orders
|
220 |
+
if ( ! $order instanceof \WC_Order || 'shop_order' !== get_post_type( Order_Compatibility::get_prop( $order, 'id' ) ) ) {
|
221 |
+
return;
|
222 |
+
}
|
223 |
+
|
224 |
+
$gateway = $this->get_order_gateway( $order );
|
225 |
+
|
226 |
+
if ( ! $gateway ) {
|
227 |
+
return;
|
228 |
+
}
|
229 |
+
|
230 |
+
if ( ! $gateway->get_capture_handler()->is_order_ready_for_capture( $order ) ) {
|
231 |
+
return;
|
232 |
+
}
|
233 |
+
|
234 |
+
$tooltip = '';
|
235 |
+
$classes = array(
|
236 |
+
'button',
|
237 |
+
'wc-square-payment-gateway-capture',
|
238 |
+
'wc-' . $gateway->get_id_dasherized() . '-capture',
|
239 |
+
);
|
240 |
+
|
241 |
+
// indicate if the partial-capture UI can be shown
|
242 |
+
if ( $gateway->supports_credit_card_partial_capture() && $gateway->is_partial_capture_enabled() ) {
|
243 |
+
$classes[] = 'partial-capture';
|
244 |
+
} elseif ( $gateway->get_capture_handler()->order_can_be_captured( $order ) ) {
|
245 |
+
$classes[] = 'button-primary';
|
246 |
+
}
|
247 |
+
|
248 |
+
// ensure that the authorization is still valid for capture
|
249 |
+
if ( ! $gateway->get_capture_handler()->order_can_be_captured( $order ) ) {
|
250 |
+
|
251 |
+
$classes[] = 'tips disabled';
|
252 |
+
|
253 |
+
// add some tooltip wording explaining why this cannot be captured
|
254 |
+
if ( $gateway->get_capture_handler()->is_order_fully_captured( $order ) ) {
|
255 |
+
$tooltip = esc_html__( 'This charge has been fully captured.', 'woocommerce-square' );
|
256 |
+
} elseif ( $gateway->get_order_meta( $order, 'trans_date' ) && $gateway->get_capture_handler()->has_order_authorization_expired( $order ) ) {
|
257 |
+
$tooltip = esc_html__( 'This charge can no longer be captured.', 'woocommerce-square' );
|
258 |
+
} else {
|
259 |
+
$tooltip = esc_html__( 'This charge cannot be captured.', 'woocommerce-square' );
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
?>
|
264 |
+
|
265 |
+
<button type="button" class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>" <?php echo ( $tooltip ) ? 'data-tip="' . esc_html( $tooltip ) . '"' : ''; ?>><?php esc_html_e( 'Capture Charge', 'woocommerce-square' ); ?></button>
|
266 |
+
|
267 |
+
<?php
|
268 |
+
|
269 |
+
// add the partial capture UI HTML
|
270 |
+
if ( $gateway->supports_credit_card_partial_capture() && $gateway->is_partial_capture_enabled() ) {
|
271 |
+
$this->output_partial_capture_html( $order, $gateway );
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Outputs the partial capture UI HTML.
|
278 |
+
*
|
279 |
+
* @since 3.0.0
|
280 |
+
*
|
281 |
+
* @param \WC_Order $order order object
|
282 |
+
* @param Payment_Gateway $gateway gateway instance
|
283 |
+
*/
|
284 |
+
protected function output_partial_capture_html( \WC_Order $order, Payment_Gateway $gateway ) {
|
285 |
+
|
286 |
+
$authorization_total = $gateway->get_capture_handler()->get_order_authorization_amount( $order );
|
287 |
+
$total_captured = $gateway->get_order_meta( $order, 'capture_total' );
|
288 |
+
$remaining_total = Square_Helper::number_format( (float) $order->get_total() - (float) $total_captured );
|
289 |
+
|
290 |
+
include( $this->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-order-partial-capture.php' );
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Processes a capture via AJAX.
|
296 |
+
*
|
297 |
+
* @internal
|
298 |
+
*
|
299 |
+
* @since 3.0.0
|
300 |
+
*/
|
301 |
+
public function ajax_process_capture() {
|
302 |
+
|
303 |
+
check_ajax_referer( 'wc_' . $this->get_plugin()->get_id() . '_capture_charge', 'nonce' );
|
304 |
+
|
305 |
+
$gateway_id = Square_Helper::get_request( 'gateway_id' );
|
306 |
+
|
307 |
+
if ( ! $this->get_plugin()->has_gateway( $gateway_id ) ) {
|
308 |
+
die();
|
309 |
+
}
|
310 |
+
|
311 |
+
$gateway = $this->get_plugin()->get_gateway( $gateway_id );
|
312 |
+
|
313 |
+
try {
|
314 |
+
|
315 |
+
$order_id = Square_Helper::get_request( 'order_id' );
|
316 |
+
$order = wc_get_order( $order_id );
|
317 |
+
|
318 |
+
if ( ! $order ) {
|
319 |
+
throw new \Exception( 'Invalid order ID' );
|
320 |
+
}
|
321 |
+
|
322 |
+
if ( ! current_user_can( 'edit_shop_order', $order_id ) ) {
|
323 |
+
throw new \Exception( 'Invalid permissions' );
|
324 |
+
}
|
325 |
+
|
326 |
+
if ( Order_Compatibility::get_prop( $order, 'payment_method' ) !== $gateway->get_id() ) {
|
327 |
+
throw new \Exception( 'Invalid payment method' );
|
328 |
+
}
|
329 |
+
|
330 |
+
$amount_captured = (float) $gateway->get_order_meta( $order, 'capture_total' );
|
331 |
+
|
332 |
+
if ( Square_Helper::get_request( 'amount' ) ) {
|
333 |
+
$amount = (float) Square_Helper::get_request( 'amount' );
|
334 |
+
} else {
|
335 |
+
$amount = $order->get_total();
|
336 |
+
}
|
337 |
+
|
338 |
+
$result = $gateway->get_capture_handler()->perform_capture( $order, $amount );
|
339 |
+
|
340 |
+
if ( empty( $result['success'] ) ) {
|
341 |
+
throw new \Exception( $result['message'] );
|
342 |
+
}
|
343 |
+
|
344 |
+
wp_send_json_success( array(
|
345 |
+
'message' => html_entity_decode( wp_strip_all_tags( $result['message'] ) ), // ensure any HTML tags are removed and the currency symbol entity is decoded
|
346 |
+
) );
|
347 |
+
|
348 |
+
} catch ( \Exception $e ) {
|
349 |
+
|
350 |
+
wp_send_json_error( array(
|
351 |
+
'message' => $e->getMessage(),
|
352 |
+
) );
|
353 |
+
}
|
354 |
+
}
|
355 |
+
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Gets the gateway object from an order.
|
359 |
+
*
|
360 |
+
* @since 3.0.0
|
361 |
+
*
|
362 |
+
* @param \WC_Order $order order object
|
363 |
+
* @return Payment_Gateway
|
364 |
+
*/
|
365 |
+
protected function get_order_gateway( \WC_Order $order ) {
|
366 |
+
|
367 |
+
$capture_gateway = null;
|
368 |
+
|
369 |
+
$payment_method = Order_Compatibility::get_prop( $order, 'payment_method' );
|
370 |
+
|
371 |
+
if ( $this->get_plugin()->has_gateway( $payment_method ) ) {
|
372 |
+
|
373 |
+
$gateway = $this->get_plugin()->get_gateway( $payment_method );
|
374 |
+
|
375 |
+
// ensure that it supports captures
|
376 |
+
if ( $gateway->supports_credit_card_capture() ) {
|
377 |
+
$capture_gateway = $gateway;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
return $capture_gateway;
|
382 |
+
}
|
383 |
+
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Gets the plugin instance.
|
387 |
+
*
|
388 |
+
* @since 3.0.0
|
389 |
+
*
|
390 |
+
* @return Payment_Gateway_Plugin the plugin instance
|
391 |
+
*/
|
392 |
+
protected function get_plugin() {
|
393 |
+
|
394 |
+
return $this->plugin;
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Captures an order on status change to a "paid" status.
|
399 |
+
*
|
400 |
+
* @internal
|
401 |
+
*
|
402 |
+
* @since 3.0.0
|
403 |
+
*
|
404 |
+
* @param int $order_id order ID
|
405 |
+
* @param string $old_status status being changed
|
406 |
+
* @param string $new_status new order status
|
407 |
+
*/
|
408 |
+
public function maybe_capture_paid_order( $order_id, $old_status, $new_status ) {
|
409 |
+
|
410 |
+
wc_deprecated_function( __METHOD__, '3.0.0' );
|
411 |
+
}
|
412 |
+
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Determines if an order is ready for capture.
|
416 |
+
*
|
417 |
+
* @since 3.0.0
|
418 |
+
*
|
419 |
+
* @param \WC_Order $order order object
|
420 |
+
* @return bool
|
421 |
+
*/
|
422 |
+
protected function is_order_ready_for_capture( \WC_Order $order ) {
|
423 |
+
|
424 |
+
wc_deprecated_function( __METHOD__, '3.0.0' );
|
425 |
+
|
426 |
+
$gateway = $this->get_order_gateway( $order );
|
427 |
+
|
428 |
+
if ( ! $gateway ) {
|
429 |
+
return false;
|
430 |
+
}
|
431 |
+
|
432 |
+
return $gateway->get_capture_handler()->is_order_ready_for_capture( $order );
|
433 |
+
}
|
434 |
+
}
|
includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_Payment_Token_Editor.php
ADDED
@@ -0,0 +1,668 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Admin;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Direct;
|
5 |
+
use WooCommerce\Square\Plugin;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
8 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Token;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) or exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* The token editor.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Payment_Gateway_Admin_Payment_Token_Editor {
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Payment_Gateway_Direct the gateway object **/
|
21 |
+
protected $gateway;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Constructs the editor.
|
26 |
+
*
|
27 |
+
* @since 3.0.0
|
28 |
+
*
|
29 |
+
* @param Payment_Gateway_Direct the gateway object
|
30 |
+
*/
|
31 |
+
public function __construct( Payment_Gateway_Direct $gateway ) {
|
32 |
+
|
33 |
+
$this->gateway = $gateway;
|
34 |
+
|
35 |
+
// Load the editor scripts and styles
|
36 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
|
37 |
+
|
38 |
+
// Display the tokens markup inside the editor
|
39 |
+
add_action( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_tokens', array( $this, 'display_tokens' ) );
|
40 |
+
|
41 |
+
/** AJAX actions **/
|
42 |
+
|
43 |
+
// Get the blank token markup via AJAX
|
44 |
+
add_action( 'wp_ajax_wc_payment_gateway_' . $this->get_gateway()->get_id() . '_admin_get_blank_payment_token', array( $this, 'ajax_get_blank_token' ) );
|
45 |
+
|
46 |
+
// Remove a token via AJAX
|
47 |
+
add_action( 'wp_ajax_wc_payment_gateway_' . $this->get_gateway()->get_id() . '_admin_remove_payment_token', array( $this, 'ajax_remove_token' ) );
|
48 |
+
|
49 |
+
// Refresh the tokens via AJAX
|
50 |
+
add_action( 'wp_ajax_wc_payment_gateway_' . $this->get_gateway()->get_id() . '_admin_refresh_payment_tokens', array( $this, 'ajax_refresh_tokens' ) );
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Load the editor scripts and styles.
|
56 |
+
*
|
57 |
+
* @since 3.0.0
|
58 |
+
*/
|
59 |
+
public function enqueue_scripts_styles() {
|
60 |
+
|
61 |
+
// Stylesheet
|
62 |
+
wp_enqueue_style( 'payment-gateway-token-editor', $this->get_gateway()->get_plugin()->get_plugin_url() . '/assets/css/admin/wc-square-payment-gateway-token-editor.min.css', array(), Plugin::VERSION );
|
63 |
+
|
64 |
+
// Main editor script
|
65 |
+
wp_enqueue_script( 'payment-gateway-token-editor', $this->get_gateway()->get_plugin()->get_plugin_url() . '/assets/js/admin/wc-square-payment-gateway-token-editor.min.js', array( 'jquery' ), Plugin::VERSION, true );
|
66 |
+
|
67 |
+
wp_localize_script( 'payment-gateway-token-editor', 'wc_payment_gateway_token_editor', array(
|
68 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
69 |
+
'actions' => array(
|
70 |
+
'remove_token' => array(
|
71 |
+
'ays' => esc_html__( 'Are you sure you want to remove this token?', 'woocommerce-square' ),
|
72 |
+
'nonce' => wp_create_nonce( 'wc_payment_gateway_admin_remove_payment_token' ),
|
73 |
+
),
|
74 |
+
'add_token' => array(
|
75 |
+
'nonce' => wp_create_nonce( 'wc_payment_gateway_admin_get_blank_payment_token' ),
|
76 |
+
),
|
77 |
+
'refresh' => array(
|
78 |
+
'nonce' => wp_create_nonce( 'wc_payment_gateway_admin_refresh_payment_tokens' ),
|
79 |
+
),
|
80 |
+
'save' => array(
|
81 |
+
'error' => esc_html__( 'Invalid token data', 'woocommerce-square' ),
|
82 |
+
),
|
83 |
+
),
|
84 |
+
'i18n' => array(
|
85 |
+
'general_error' => esc_html__( 'An error occurred. Please try again.', 'woocommerce-square' ),
|
86 |
+
),
|
87 |
+
) );
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Display the token editor.
|
93 |
+
*
|
94 |
+
* @since 3.0.0
|
95 |
+
* @param int $user_id the user ID
|
96 |
+
*/
|
97 |
+
public function display( $user_id ) {
|
98 |
+
|
99 |
+
$id = $this->get_gateway()->get_id();
|
100 |
+
$title = $this->get_title();
|
101 |
+
$columns = $this->get_columns();
|
102 |
+
$actions = $this->get_actions();
|
103 |
+
|
104 |
+
include( $this->get_gateway()->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-user-payment-token-editor.php' );
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Display the tokens.
|
110 |
+
*
|
111 |
+
* @since 3.0.0
|
112 |
+
* @param int $user_id the user ID
|
113 |
+
*/
|
114 |
+
public function display_tokens( $user_id ) {
|
115 |
+
|
116 |
+
$tokens = $this->get_tokens( $user_id );
|
117 |
+
|
118 |
+
$fields = $this->get_fields();
|
119 |
+
$input_name = $this->get_input_name();
|
120 |
+
$actions = $this->get_token_actions();
|
121 |
+
$type = $this->get_payment_type();
|
122 |
+
|
123 |
+
$index = 0;
|
124 |
+
|
125 |
+
foreach ( $tokens as $token ) {
|
126 |
+
|
127 |
+
include( $this->get_gateway()->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-user-payment-token-editor-token.php' );
|
128 |
+
|
129 |
+
$index++;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Save the token editor.
|
136 |
+
*
|
137 |
+
* @since 3.0.0
|
138 |
+
* @param int $user_id the user ID
|
139 |
+
*/
|
140 |
+
public function save( $user_id ) {
|
141 |
+
|
142 |
+
$tokens = ( isset( $_POST[ $this->get_input_name() ] ) ) ? $_POST[ $this->get_input_name() ] : array();
|
143 |
+
|
144 |
+
$built_tokens = array();
|
145 |
+
|
146 |
+
foreach ( $tokens as $data ) {
|
147 |
+
|
148 |
+
$token_id = $data['id'];
|
149 |
+
|
150 |
+
unset( $data['id'] );
|
151 |
+
|
152 |
+
if ( ! $token_id ) {
|
153 |
+
continue;
|
154 |
+
}
|
155 |
+
|
156 |
+
if ( 'credit_card' === $data['type'] ) {
|
157 |
+
$data = $this->prepare_expiry_date( $data );
|
158 |
+
}
|
159 |
+
|
160 |
+
// Set the default method
|
161 |
+
$data['default'] = $token_id === Square_Helper::get_post( $this->get_input_name() . '_default' );
|
162 |
+
|
163 |
+
if ( $data = $this->validate_token_data( $token_id, $data ) ) {
|
164 |
+
$built_tokens[ $token_id ] = $this->build_token( $user_id, $token_id, $data );
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
$this->update_tokens( $user_id, $built_tokens );
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Add a token via AJAX.
|
174 |
+
*
|
175 |
+
* @since 3.0.0
|
176 |
+
*/
|
177 |
+
public function ajax_get_blank_token() {
|
178 |
+
|
179 |
+
check_ajax_referer( 'wc_payment_gateway_admin_get_blank_payment_token', 'security' );
|
180 |
+
|
181 |
+
$index = Square_Helper::get_request( 'index' );
|
182 |
+
|
183 |
+
if ( $index ) {
|
184 |
+
|
185 |
+
$fields = $this->get_fields();
|
186 |
+
$input_name = $this->get_input_name();
|
187 |
+
$actions = $this->get_token_actions();
|
188 |
+
$type = $this->get_payment_type();
|
189 |
+
$user_id = 0;
|
190 |
+
|
191 |
+
$token = array_fill_keys( array_keys( $fields ), '' );
|
192 |
+
$token['id'] = '';
|
193 |
+
$token['expiry'] = '';
|
194 |
+
$token['default'] = false;
|
195 |
+
|
196 |
+
ob_start();
|
197 |
+
|
198 |
+
include( $this->get_gateway()->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-user-payment-token-editor-token.php' );
|
199 |
+
|
200 |
+
$html = ob_get_clean();
|
201 |
+
|
202 |
+
wp_send_json_success( $html );
|
203 |
+
|
204 |
+
} else {
|
205 |
+
|
206 |
+
wp_send_json_error();
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Remove a token via AJAX.
|
213 |
+
*
|
214 |
+
* @since 3.0.0
|
215 |
+
*/
|
216 |
+
public function ajax_remove_token() {
|
217 |
+
|
218 |
+
try {
|
219 |
+
|
220 |
+
if ( ! check_ajax_referer( 'wc_payment_gateway_admin_remove_payment_token', 'security' ) ) {
|
221 |
+
throw new \Exception( 'Invalid nonce' );
|
222 |
+
}
|
223 |
+
|
224 |
+
$user_id = Square_Helper::get_request( 'user_id' );
|
225 |
+
$token_id = Square_Helper::get_request( 'token_id' );
|
226 |
+
|
227 |
+
if ( ! $user_id ) {
|
228 |
+
throw new \Exception( 'User ID is missing' );
|
229 |
+
}
|
230 |
+
|
231 |
+
if ( ! $token_id ) {
|
232 |
+
throw new \Exception( 'Token ID is missing' );
|
233 |
+
}
|
234 |
+
|
235 |
+
if ( $this->remove_token( $user_id, $token_id ) ) {
|
236 |
+
wp_send_json_success();
|
237 |
+
} else {
|
238 |
+
throw new \Exception( 'Could not remove token' );
|
239 |
+
}
|
240 |
+
|
241 |
+
} catch ( \Exception $e ) {
|
242 |
+
|
243 |
+
wp_send_json_error( $e->getMessage() );
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Refresh the tokens list via AJAX.
|
250 |
+
*
|
251 |
+
* @since 3.0.0
|
252 |
+
*/
|
253 |
+
public function ajax_refresh_tokens() {
|
254 |
+
|
255 |
+
try {
|
256 |
+
|
257 |
+
if ( ! check_ajax_referer( 'wc_payment_gateway_admin_refresh_payment_tokens', 'security', false ) ) {
|
258 |
+
throw new \Exception( 'Invalid nonce' );
|
259 |
+
}
|
260 |
+
|
261 |
+
$user_id = Square_Helper::get_request( 'user_id' );
|
262 |
+
|
263 |
+
if ( ! $user_id ) {
|
264 |
+
throw new \Exception( 'User ID is missing' );
|
265 |
+
}
|
266 |
+
|
267 |
+
ob_start();
|
268 |
+
|
269 |
+
$this->display_tokens( $user_id );
|
270 |
+
|
271 |
+
$html = ob_get_clean();
|
272 |
+
|
273 |
+
wp_send_json_success( trim( $html ) );
|
274 |
+
|
275 |
+
} catch ( \Exception $e ) {
|
276 |
+
|
277 |
+
wp_send_json_error( $e->getMessage() );
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Build a token object from data saved in the admin.
|
284 |
+
*
|
285 |
+
* This method allows concrete gateways to add special token data.
|
286 |
+
* See Authorize.net CIM for an example.
|
287 |
+
*
|
288 |
+
* @since 3.0.0
|
289 |
+
*
|
290 |
+
* @param int $user_id the user ID
|
291 |
+
* @param string $token_id the token ID
|
292 |
+
* @param array $data the token data
|
293 |
+
* @return Payment_Gateway_Payment_Token the payment token object
|
294 |
+
*/
|
295 |
+
protected function build_token( $user_id, $token_id, $data ) {
|
296 |
+
return $this->get_gateway()->get_payment_tokens_handler()->build_token( $token_id, $data );
|
297 |
+
}
|
298 |
+
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Update the user's token data.
|
302 |
+
*
|
303 |
+
* @since 3.0.0
|
304 |
+
* @param int $user_id the user ID
|
305 |
+
* @param array the token objects
|
306 |
+
*/
|
307 |
+
protected function update_tokens( $user_id, $tokens ) {
|
308 |
+
|
309 |
+
$this->get_gateway()->get_payment_tokens_handler()->update_tokens( $user_id, $tokens, $this->get_gateway()->get_environment() );
|
310 |
+
}
|
311 |
+
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Remove a specific token.
|
315 |
+
*
|
316 |
+
* @since 3.0.0
|
317 |
+
* @param int $user_id the user ID
|
318 |
+
* @param string $token_id the token ID
|
319 |
+
* @return bool whether the token was successfully removed
|
320 |
+
*/
|
321 |
+
protected function remove_token( $user_id, $token_id ) {
|
322 |
+
|
323 |
+
return $this->get_gateway()->get_payment_tokens_handler()->remove_token( $user_id, $token_id, $this->get_gateway()->get_environment() );
|
324 |
+
}
|
325 |
+
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Validate a token's data before saving.
|
329 |
+
*
|
330 |
+
* Concrete gateways can override this to provide their own validation.
|
331 |
+
*
|
332 |
+
* @since 3.0.0
|
333 |
+
* @param array $data the token data
|
334 |
+
* @return array|bool the validated token data or false if the token should not be saved
|
335 |
+
*/
|
336 |
+
protected function validate_token_data( $token_id, $data ) {
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Filter the validated token data.
|
340 |
+
*
|
341 |
+
* @since 3.0.0
|
342 |
+
* @param array $data the validated token data
|
343 |
+
* @param string $token_id the token ID
|
344 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor the token editor instance
|
345 |
+
* @return array the validated token data
|
346 |
+
*/
|
347 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_validate_token_data', $data, $token_id, $this );
|
348 |
+
}
|
349 |
+
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Correctly format a credit card expiration date for storage.
|
353 |
+
*
|
354 |
+
* @since 3.0.0
|
355 |
+
* @param array $data
|
356 |
+
* @return array
|
357 |
+
*/
|
358 |
+
protected function prepare_expiry_date( $data ) {
|
359 |
+
|
360 |
+
// expiry date must be present, include a forward slash and be 5 characters (MM/YY)
|
361 |
+
if ( ! $data['expiry'] || ! Square_Helper::str_exists( $data['expiry'], '/' ) || 5 !== strlen( $data['expiry'] ) ) {
|
362 |
+
unset( $data['expiry'] );
|
363 |
+
return $data;
|
364 |
+
}
|
365 |
+
|
366 |
+
list( $data['exp_month'], $data['exp_year'] ) = explode( '/', $data['expiry'] );
|
367 |
+
|
368 |
+
unset( $data['expiry'] );
|
369 |
+
|
370 |
+
return $data;
|
371 |
+
}
|
372 |
+
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Get the stored tokens for a user.
|
376 |
+
*
|
377 |
+
* @since 3.0.0
|
378 |
+
* @param int $user_id the user ID
|
379 |
+
* @return array the tokens in db format
|
380 |
+
*/
|
381 |
+
protected function get_tokens( $user_id ) {
|
382 |
+
|
383 |
+
// Clear any cached tokens
|
384 |
+
$this->get_gateway()->get_payment_tokens_handler()->clear_transient( $user_id );
|
385 |
+
|
386 |
+
// get the customer ID separately so it's never auto-created from the admin
|
387 |
+
$customer_id = $this->get_gateway()->get_customer_id( $user_id, array(
|
388 |
+
'autocreate' => false,
|
389 |
+
) );
|
390 |
+
|
391 |
+
$stored_tokens = $this->get_gateway()->get_payment_tokens_handler()->get_tokens( $user_id, array(
|
392 |
+
'customer_id' => $customer_id,
|
393 |
+
) );
|
394 |
+
|
395 |
+
$tokens = array();
|
396 |
+
|
397 |
+
foreach( $stored_tokens as $token ) {
|
398 |
+
|
399 |
+
$token_id = $token->get_id();
|
400 |
+
|
401 |
+
// Set the token data
|
402 |
+
$tokens[ $token_id ] = $token->to_datastore_format();
|
403 |
+
|
404 |
+
$tokens[ $token_id ]['id'] = $token_id;
|
405 |
+
|
406 |
+
// Set the credit card expiration date
|
407 |
+
if ( $token->is_credit_card() ) {
|
408 |
+
$tokens[ $token_id ]['expiry'] = $token->get_exp_month() && $token->get_exp_year() ? $token->get_exp_date() : '';
|
409 |
+
}
|
410 |
+
|
411 |
+
$tokens[ $token_id ]['default'] = $token->is_default();
|
412 |
+
|
413 |
+
// Parse against the editor field IDs so we don't have to isset throughout the HTML
|
414 |
+
$tokens[ $token_id ] = wp_parse_args( $tokens[ $token_id ], array_fill_keys( array_keys( $this->get_fields() ), '' ) );
|
415 |
+
}
|
416 |
+
|
417 |
+
return $tokens;
|
418 |
+
}
|
419 |
+
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Get the editor title.
|
423 |
+
*
|
424 |
+
* @since 3.0.0
|
425 |
+
* @return string
|
426 |
+
*/
|
427 |
+
protected function get_title() {
|
428 |
+
|
429 |
+
$title = $this->get_gateway()->get_title();
|
430 |
+
|
431 |
+
// Append the environment name if there are multiple
|
432 |
+
if ( $this->get_gateway()->get_plugin()->get_admin_user_handler()->has_multiple_environments() ) {
|
433 |
+
$title .= ' ' . sprintf( esc_html__( '(%s)', 'woocommerce-square' ), $this->get_gateway()->get_environment_name() );
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Filters the token editor name.
|
438 |
+
*
|
439 |
+
* @since 3.0.0
|
440 |
+
*
|
441 |
+
* @param string $title the editor title
|
442 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor $editor the editor object
|
443 |
+
*/
|
444 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_title', $title, $this );
|
445 |
+
}
|
446 |
+
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Get the editor columns.
|
450 |
+
*
|
451 |
+
* @since 3.0.0
|
452 |
+
* @return array
|
453 |
+
*/
|
454 |
+
protected function get_columns() {
|
455 |
+
|
456 |
+
$fields = $this->get_fields();
|
457 |
+
$columns = array();
|
458 |
+
|
459 |
+
foreach ( $fields as $field_id => $field ) {
|
460 |
+
$columns[ $field_id ] = isset( $field['label'] ) ? $field['label'] : '';
|
461 |
+
}
|
462 |
+
|
463 |
+
$columns['default'] = esc_html__( 'Default', 'woocommerce-square' );
|
464 |
+
$columns['actions'] = '';
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Filters the admin token editor columns.
|
468 |
+
*
|
469 |
+
* @since 3.0.0
|
470 |
+
*
|
471 |
+
* @param array $columns
|
472 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor $editor the editor object
|
473 |
+
*/
|
474 |
+
$columns = apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_columns', $columns, $this );
|
475 |
+
|
476 |
+
return $columns;
|
477 |
+
}
|
478 |
+
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Get the editor fields.
|
482 |
+
*
|
483 |
+
* @since 3.0.0
|
484 |
+
* @return array
|
485 |
+
*/
|
486 |
+
protected function get_fields( $type = '' ) {
|
487 |
+
|
488 |
+
if ( ! $type ) {
|
489 |
+
$type = $this->get_gateway()->get_payment_type();
|
490 |
+
}
|
491 |
+
|
492 |
+
switch ( $type ) {
|
493 |
+
|
494 |
+
case 'credit-card' :
|
495 |
+
|
496 |
+
// Define the credit card fields
|
497 |
+
$fields = array(
|
498 |
+
'id' => array(
|
499 |
+
'label' => esc_html__( 'Token ID', 'woocommerce-square' ),
|
500 |
+
'editable' => ! $this->get_gateway()->get_api()->supports_get_tokenized_payment_methods(),
|
501 |
+
'required' => true,
|
502 |
+
),
|
503 |
+
'card_type' => array(
|
504 |
+
'label' => esc_html__( 'Card Type', 'woocommerce-square' ),
|
505 |
+
'type' => 'select',
|
506 |
+
'options' => $this->get_card_type_options(),
|
507 |
+
),
|
508 |
+
'last_four' => array(
|
509 |
+
'label' => esc_html__( 'Last Four', 'woocommerce-square' ),
|
510 |
+
'attributes' => array(
|
511 |
+
'pattern' => '[0-9]{4}',
|
512 |
+
'maxlength' => 4,
|
513 |
+
),
|
514 |
+
),
|
515 |
+
'expiry' => array(
|
516 |
+
'label' => esc_html__( 'Expiration (MM/YY)', 'woocommerce-square' ),
|
517 |
+
'attributes' => array(
|
518 |
+
'placeholder' => 'MM/YY',
|
519 |
+
'pattern' => '(0[1-9]|1[012])[- /.]\d\d',
|
520 |
+
'maxlength' => 5,
|
521 |
+
),
|
522 |
+
),
|
523 |
+
);
|
524 |
+
|
525 |
+
break;
|
526 |
+
|
527 |
+
default :
|
528 |
+
$fields = array();
|
529 |
+
}
|
530 |
+
|
531 |
+
// Parse each field against the defaults
|
532 |
+
foreach ( $fields as $field_id => $field ) {
|
533 |
+
|
534 |
+
$fields[ $field_id ] = wp_parse_args( $field, array(
|
535 |
+
'label' => '',
|
536 |
+
'type' => 'text',
|
537 |
+
'attributes' => array(),
|
538 |
+
'editable' => true,
|
539 |
+
'required' => false,
|
540 |
+
) );
|
541 |
+
}
|
542 |
+
|
543 |
+
/**
|
544 |
+
* Filters the admin token editor fields.
|
545 |
+
*
|
546 |
+
* @since 3.0.0
|
547 |
+
*
|
548 |
+
* @param array $fields
|
549 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor $editor the editor object
|
550 |
+
*/
|
551 |
+
$fields = apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_fields', $fields, $this );
|
552 |
+
|
553 |
+
return $fields;
|
554 |
+
}
|
555 |
+
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Get the token payment type.
|
559 |
+
*
|
560 |
+
* @since 3.0.0
|
561 |
+
* @return string
|
562 |
+
*/
|
563 |
+
protected function get_payment_type() {
|
564 |
+
|
565 |
+
return str_replace( '-', '_', $this->get_gateway()->get_payment_type() );
|
566 |
+
}
|
567 |
+
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Get the credit card type field options.
|
571 |
+
*
|
572 |
+
* @since 3.0.0
|
573 |
+
* @return array
|
574 |
+
*/
|
575 |
+
protected function get_card_type_options() {
|
576 |
+
|
577 |
+
$card_types = $this->get_gateway()->get_card_types();
|
578 |
+
$options = array();
|
579 |
+
|
580 |
+
foreach ( $card_types as $card_type ) {
|
581 |
+
|
582 |
+
$card_type = Payment_Gateway_Helper::normalize_card_type( $card_type );
|
583 |
+
|
584 |
+
$options[ $card_type ] = Payment_Gateway_Helper::payment_type_to_name( $card_type );
|
585 |
+
}
|
586 |
+
|
587 |
+
return $options;
|
588 |
+
}
|
589 |
+
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Get the HTML name for the token fields.
|
593 |
+
*
|
594 |
+
* @since 3.0.0
|
595 |
+
* @return string
|
596 |
+
*/
|
597 |
+
protected function get_input_name() {
|
598 |
+
|
599 |
+
return 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_tokens';
|
600 |
+
}
|
601 |
+
|
602 |
+
|
603 |
+
/**
|
604 |
+
* Get the available editor actions.
|
605 |
+
*
|
606 |
+
* @since 3.0.0
|
607 |
+
* @return array
|
608 |
+
*/
|
609 |
+
protected function get_actions() {
|
610 |
+
|
611 |
+
$actions = array();
|
612 |
+
|
613 |
+
if ( $this->get_gateway()->get_api()->supports_get_tokenized_payment_methods() ) {
|
614 |
+
$actions['refresh'] = esc_html__( 'Refresh', 'woocommerce-square' );
|
615 |
+
} else {
|
616 |
+
$actions['add-new'] = esc_html__( 'Add New', 'woocommerce-square' );
|
617 |
+
}
|
618 |
+
|
619 |
+
$actions['save'] = esc_html__( 'Save', 'woocommerce-square' );
|
620 |
+
|
621 |
+
/**
|
622 |
+
* Filters the payment token editor actions.
|
623 |
+
*
|
624 |
+
* @since 3.0.0
|
625 |
+
*
|
626 |
+
* @param array $actions the actions
|
627 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor $editor the editor object
|
628 |
+
*/
|
629 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_actions', $actions, $this );
|
630 |
+
}
|
631 |
+
|
632 |
+
|
633 |
+
/**
|
634 |
+
* Get the available token actions.
|
635 |
+
*
|
636 |
+
* @since 3.0.0
|
637 |
+
* @return array
|
638 |
+
*/
|
639 |
+
protected function get_token_actions() {
|
640 |
+
|
641 |
+
$actions = array(
|
642 |
+
'remove' => esc_html__( 'Remove', 'woocommerce-square' ),
|
643 |
+
);
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Filters the token actions.
|
647 |
+
*
|
648 |
+
* @since 3.0.0
|
649 |
+
*
|
650 |
+
* @param array $actions the token actions
|
651 |
+
* @param Payment_Gateway_Admin_Payment_Token_Editor $editor the editor object
|
652 |
+
*/
|
653 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_token_editor_token_actions', $actions, $this );
|
654 |
+
}
|
655 |
+
|
656 |
+
|
657 |
+
/**
|
658 |
+
* Gets the gateway object.
|
659 |
+
*
|
660 |
+
* @since 3.0.0
|
661 |
+
*
|
662 |
+
* @return Payment_Gateway_Direct the gateway object
|
663 |
+
*/
|
664 |
+
protected function get_gateway() {
|
665 |
+
|
666 |
+
return $this->gateway;
|
667 |
+
}
|
668 |
+
}
|
includes/Framework/PaymentGateway/Admin/Payment_Gateway_Admin_User_Handler.php
ADDED
@@ -0,0 +1,381 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Admin;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Plugin;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Handle the admin user profile settings.
|
10 |
+
*
|
11 |
+
* @since 3.0.0
|
12 |
+
*/
|
13 |
+
class Payment_Gateway_Admin_User_Handler {
|
14 |
+
|
15 |
+
/** @var \Payment_Gateway_Plugin the plugin instance **/
|
16 |
+
protected $plugin;
|
17 |
+
|
18 |
+
/** @var array the token editor for each gateway **/
|
19 |
+
protected $token_editors = array();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Construct the user handler.
|
23 |
+
*
|
24 |
+
* @since 3.0.0
|
25 |
+
* @param \Payment_Gateway_Plugin The plugin instance
|
26 |
+
*/
|
27 |
+
public function __construct( Payment_Gateway_Plugin $plugin ) {
|
28 |
+
|
29 |
+
$this->plugin = $plugin;
|
30 |
+
|
31 |
+
// Set up a token editor for each gateway
|
32 |
+
add_action( 'admin_init', array( $this, 'init_token_editors' ) );
|
33 |
+
|
34 |
+
// Add the settings section
|
35 |
+
add_action( 'show_user_profile', array( $this, 'add_profile_section' ) );
|
36 |
+
add_action( 'edit_user_profile', array( $this, 'add_profile_section' ) );
|
37 |
+
|
38 |
+
// Save the settings
|
39 |
+
add_action( 'personal_options_update', array( $this, 'save_profile_fields' ) );
|
40 |
+
add_action( 'edit_user_profile_update', array( $this, 'save_profile_fields' ) );
|
41 |
+
|
42 |
+
// Display the token editor markup inside the profile section
|
43 |
+
add_action( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_user_profile', array( $this, 'display_token_editors' ) );
|
44 |
+
|
45 |
+
// Display the customer ID field markup inside the profile section
|
46 |
+
add_action( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_user_profile', array( $this, 'display_customer_id_fields' ) );
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Set up a token editor for each gateway.
|
52 |
+
*
|
53 |
+
* @since 3.0.0
|
54 |
+
*/
|
55 |
+
public function init_token_editors() {
|
56 |
+
|
57 |
+
foreach ( $this->get_tokenized_gateways() as $gateway ) {
|
58 |
+
|
59 |
+
if ( ! $gateway->supports_token_editor() ) {
|
60 |
+
continue;
|
61 |
+
}
|
62 |
+
|
63 |
+
$this->token_editors[ $gateway->get_id() ] = $gateway->get_payment_tokens_handler()->get_token_editor();
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Display the customer profile settings markup.
|
70 |
+
*
|
71 |
+
* @since 3.0.0
|
72 |
+
* @param \WP_User $user The user object
|
73 |
+
*/
|
74 |
+
public function add_profile_section( $user ) {
|
75 |
+
|
76 |
+
if ( ! $this->is_supported() || ! current_user_can( 'manage_woocommerce' ) ) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
|
80 |
+
$user_id = $user->ID;
|
81 |
+
$plugin_id = $this->get_plugin()->get_id();
|
82 |
+
$section_title = $this->get_title();
|
83 |
+
$section_description = $this->get_description();
|
84 |
+
|
85 |
+
include( $this->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-user-profile-section.php' );
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Display the token editor markup.
|
91 |
+
*
|
92 |
+
* @since 3.0.0
|
93 |
+
* @param \WP_User $user The user object
|
94 |
+
*/
|
95 |
+
public function display_token_editors( $user ) {
|
96 |
+
|
97 |
+
foreach ( $this->get_token_editors() as $gateway_id => $editor ) {
|
98 |
+
|
99 |
+
$gateway = $this->get_plugin()->get_gateway( $gateway_id );
|
100 |
+
|
101 |
+
// if the gateway supports a customer ID but none is saved, don't display the token tables
|
102 |
+
if ( $gateway && $gateway->supports_customer_id() && ! $gateway->get_customer_id( $user->ID, array( 'autocreate' => false ) ) ) {
|
103 |
+
continue;
|
104 |
+
}
|
105 |
+
|
106 |
+
$editor->display( $user->ID );
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Display the customer ID field(s).
|
113 |
+
*
|
114 |
+
* @since 3.0.0
|
115 |
+
* @param \WP_User $user the user object
|
116 |
+
*/
|
117 |
+
public function display_customer_id_fields( $user ) {
|
118 |
+
|
119 |
+
foreach( $this->get_customer_id_fields( $user->ID ) as $field ) {
|
120 |
+
|
121 |
+
$label = $field['label'];
|
122 |
+
$name = $field['name'];
|
123 |
+
$value = $field['value'];
|
124 |
+
|
125 |
+
include( $this->get_plugin()->get_payment_gateway_framework_path() . '/admin/views/html-user-profile-field-customer-id.php' );
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Save the user profile section fields.
|
132 |
+
*
|
133 |
+
* @since 3.0.0
|
134 |
+
* @param int $user_id the user ID
|
135 |
+
*/
|
136 |
+
public function save_profile_fields( $user_id ) {
|
137 |
+
|
138 |
+
if ( ! $this->is_supported() || ! current_user_can( 'manage_woocommerce' ) ) {
|
139 |
+
return;
|
140 |
+
}
|
141 |
+
|
142 |
+
// Save the token data from each token editor
|
143 |
+
$this->save_tokens( $user_id );
|
144 |
+
|
145 |
+
// Save the customer IDs
|
146 |
+
$this->save_customer_ids( $user_id );
|
147 |
+
}
|
148 |
+
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Save the token data from each token editor.
|
152 |
+
*
|
153 |
+
* @since 3.0.0
|
154 |
+
* @param int $user_id the user ID
|
155 |
+
*/
|
156 |
+
protected function save_tokens( $user_id ) {
|
157 |
+
|
158 |
+
foreach ( $this->get_token_editors() as $gateway_id => $editor ) {
|
159 |
+
$editor->save( $user_id );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Save the customer IDs.
|
166 |
+
*
|
167 |
+
* @since 3.0.0
|
168 |
+
* @param int $user_id the user ID
|
169 |
+
*/
|
170 |
+
protected function save_customer_ids( $user_id ) {
|
171 |
+
|
172 |
+
foreach ( $this->get_tokenized_gateways() as $gateway ) {
|
173 |
+
|
174 |
+
if ( ! $gateway->supports_customer_id() ) {
|
175 |
+
continue;
|
176 |
+
}
|
177 |
+
|
178 |
+
if ( isset( $_POST[ $gateway->get_customer_id_user_meta_name() ] ) ) {
|
179 |
+
$gateway->update_customer_id( $user_id, trim( $_POST[ $gateway->get_customer_id_user_meta_name() ] ) );
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
|
185 |
+
/** Getter methods ******************************************************/
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Get the token editor section title.
|
190 |
+
*
|
191 |
+
* @since 3.0.0
|
192 |
+
* @return string
|
193 |
+
*/
|
194 |
+
protected function get_title() {
|
195 |
+
|
196 |
+
$plugin_title = trim( str_replace( 'WooCommerce', '', $this->get_plugin()->get_plugin_name() ) );
|
197 |
+
|
198 |
+
$title = sprintf( esc_html__( '%s Payment Tokens', 'woocommerce-square' ), $plugin_title );
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Filter the admin token editor title.
|
202 |
+
*
|
203 |
+
* @since 3.0.0
|
204 |
+
* @param string $title The section title
|
205 |
+
* @param \Payment_Gateway_Plugin $plugin The gateway plugin instance
|
206 |
+
*/
|
207 |
+
return apply_filters( 'wc_payment_gateway_admin_user_profile_title', $title, $this->get_plugin() );
|
208 |
+
}
|
209 |
+
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Get the token editor section description.
|
213 |
+
*
|
214 |
+
* @since 3.0.0
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
protected function get_description() {
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Filter the admin token editor description.
|
221 |
+
*
|
222 |
+
* @since 3.0.0
|
223 |
+
* @param string $description The section description
|
224 |
+
* @param \Payment_Gateway_Plugin $plugin The gateway plugin instance
|
225 |
+
*/
|
226 |
+
return apply_filters( 'wc_payment_gateway_admin_user_profile_description', '', $this->get_plugin() );
|
227 |
+
}
|
228 |
+
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Get the token editor objects.
|
232 |
+
*
|
233 |
+
* @since 3.0.0
|
234 |
+
* @return array
|
235 |
+
*/
|
236 |
+
protected function get_token_editors() {
|
237 |
+
return $this->token_editors;
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Get the customer ID fields for the plugin's gateways.
|
243 |
+
*
|
244 |
+
* In most cases, this will be a single field unless the plugin has multiple gateways and they
|
245 |
+
* are set to different environments.
|
246 |
+
*
|
247 |
+
* @since 3.0.0
|
248 |
+
* @param int $user_id the user ID
|
249 |
+
* @return array {
|
250 |
+
* The fields data
|
251 |
+
*
|
252 |
+
* @type string $label the field label
|
253 |
+
* @type string $name the input name
|
254 |
+
* @type string $value the input value
|
255 |
+
* }
|
256 |
+
*/
|
257 |
+
protected function get_customer_id_fields( $user_id ) {
|
258 |
+
|
259 |
+
$unique_meta_key = '';
|
260 |
+
|
261 |
+
$fields = array();
|
262 |
+
|
263 |
+
foreach ( $this->get_tokenized_gateways() as $gateway ) {
|
264 |
+
|
265 |
+
if ( ! $gateway->supports_customer_id() ) {
|
266 |
+
continue;
|
267 |
+
}
|
268 |
+
|
269 |
+
$meta_key = $gateway->get_customer_id_user_meta_name();
|
270 |
+
|
271 |
+
// If a field with this meta key has already been set, skip this gateway
|
272 |
+
if ( $meta_key === $unique_meta_key ) {
|
273 |
+
continue;
|
274 |
+
}
|
275 |
+
|
276 |
+
$label = esc_html__( 'Customer ID', 'woocommerce-square' );
|
277 |
+
|
278 |
+
// If the plugin has multiple gateways configured for multiple environments, append the environment name to keep things straight
|
279 |
+
$label .= ( $this->has_multiple_environments() ) ? ' ' . sprintf( esc_html__( '(%s)', 'woocommerce-square' ), $gateway->get_environment_name() ) : '';
|
280 |
+
|
281 |
+
$fields[] = array(
|
282 |
+
'label' => $label,
|
283 |
+
'name' => $meta_key,
|
284 |
+
'value' => $gateway->get_customer_id( $user_id, array(
|
285 |
+
'autocreate' => false,
|
286 |
+
) ),
|
287 |
+
);
|
288 |
+
|
289 |
+
$unique_meta_key = $meta_key;
|
290 |
+
}
|
291 |
+
|
292 |
+
return $fields;
|
293 |
+
}
|
294 |
+
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Get the unique environments between the plugin's gateways.
|
298 |
+
*
|
299 |
+
* @since 3.0.0
|
300 |
+
* @return array the environments in the format `$environment_id => $environment_name`
|
301 |
+
*/
|
302 |
+
protected function get_unique_environments() {
|
303 |
+
|
304 |
+
$environments = array();
|
305 |
+
|
306 |
+
foreach ( $this->get_tokenized_gateways() as $gateway ) {
|
307 |
+
$environments[ $gateway->get_environment() ] = $gateway->get_environment_name();
|
308 |
+
}
|
309 |
+
|
310 |
+
$environments = array_unique( $environments );
|
311 |
+
|
312 |
+
return $environments;
|
313 |
+
}
|
314 |
+
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Get the gateways that support tokenization and are enabled.
|
318 |
+
*
|
319 |
+
* @since 3.0.0
|
320 |
+
* @return array
|
321 |
+
*/
|
322 |
+
protected function get_tokenized_gateways() {
|
323 |
+
|
324 |
+
$gateways = array();
|
325 |
+
|
326 |
+
foreach ( $this->get_plugin()->get_gateways() as $gateway ) {
|
327 |
+
|
328 |
+
if ( $gateway->is_enabled() && $gateway->supports_tokenization() && ( $gateway->supports_token_editor() || $gateway->supports_customer_id() ) ) {
|
329 |
+
$gateways[] = $gateway;
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
return $gateways;
|
334 |
+
}
|
335 |
+
|
336 |
+
|
337 |
+
/** Conditional methods ******************************************************/
|
338 |
+
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Determine if the user profile section is supported by at least one gateway.
|
342 |
+
*
|
343 |
+
* @since 3.0.0
|
344 |
+
* @return bool
|
345 |
+
*/
|
346 |
+
protected function is_supported() {
|
347 |
+
|
348 |
+
$gateways = $this->get_tokenized_gateways();
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Filter whether the user profile section should be displayed for this gateway plugin.
|
352 |
+
*
|
353 |
+
* @since 3.0.0
|
354 |
+
* @param bool $display
|
355 |
+
* @param \Payment_Gateway_Plugin $plugin the gateway plugin instance
|
356 |
+
*/
|
357 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_display_user_profile', ! empty( $gateways ), $this->get_plugin() );
|
358 |
+
}
|
359 |
+
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Determine if the plugin has varying environments between its gateways.
|
363 |
+
*
|
364 |
+
* @since 3.0.0
|
365 |
+
* @return bool
|
366 |
+
*/
|
367 |
+
public function has_multiple_environments() {
|
368 |
+
return 1 < count( $this->get_unique_environments() );
|
369 |
+
}
|
370 |
+
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Get the plugin instance.
|
374 |
+
*
|
375 |
+
* @since 3.0.0
|
376 |
+
* @return \Payment_Gateway_Plugin the plugin instance
|
377 |
+
*/
|
378 |
+
protected function get_plugin() {
|
379 |
+
return $this->plugin;
|
380 |
+
}
|
381 |
+
}
|
includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<table class="wc_status_table widefat" cellspacing="0">
|
2 |
+
|
3 |
+
<thead>
|
4 |
+
<tr>
|
5 |
+
<th colspan="3" data-export-label="">
|
6 |
+
<?php echo esc_html( $gateway->get_method_title() ); ?>
|
7 |
+
<?php echo wc_help_tip( __( 'This section contains configuration settings for this gateway.', 'woocommerce-square' ) ); ?>
|
8 |
+
</th>
|
9 |
+
</tr>
|
10 |
+
</thead>
|
11 |
+
|
12 |
+
<tbody>
|
13 |
+
|
14 |
+
<?php
|
15 |
+
/**
|
16 |
+
* Payment Gateway System Status Start Action.
|
17 |
+
*
|
18 |
+
* Allow actors to add info the start of the gateway system status section.
|
19 |
+
*
|
20 |
+
* @since 4.3.0
|
21 |
+
*
|
22 |
+
* @param Payment_Gateway $gateway
|
23 |
+
*/
|
24 |
+
do_action( 'wc_payment_gateway_' . $gateway->get_id() . '_system_status_start', $gateway );
|
25 |
+
?>
|
26 |
+
|
27 |
+
<tr>
|
28 |
+
<td data-export-label="Environment"><?php esc_html_e( 'Environment', 'woocommerce-square' ); ?>:</td>
|
29 |
+
<td class="help"><?php echo wc_help_tip( __( 'The transaction environment for this gateway.', 'woocommerce-square' ) ); ?></td>
|
30 |
+
<td><?php echo esc_html( $environment ); ?></td>
|
31 |
+
</tr>
|
32 |
+
|
33 |
+
<?php if ( $gateway->supports_tokenization() ) : ?>
|
34 |
+
|
35 |
+
<tr>
|
36 |
+
<td data-export-label="Tokenization Enabled"><?php esc_html_e( 'Tokenization Enabled', 'woocommerce-square' ); ?>:</td>
|
37 |
+
<td class="help"><?php echo wc_help_tip( __( 'Displays whether or not tokenization is enabled for this gateway.', 'woocommerce-square' ) ); ?></td>
|
38 |
+
<td>
|
39 |
+
<?php if ( $gateway->tokenization_enabled() ) : ?>
|
40 |
+
<mark class="yes">✔</mark>
|
41 |
+
<?php else : ?>
|
42 |
+
<mark class="no">–</mark>
|
43 |
+
<?php endif; ?>
|
44 |
+
</td>
|
45 |
+
</tr>
|
46 |
+
|
47 |
+
<?php endif; ?>
|
48 |
+
|
49 |
+
<tr>
|
50 |
+
<td data-export-label="Debug Mode"><?php esc_html_e( 'Debug Mode', 'woocommerce-square' ); ?>:</td>
|
51 |
+
<td class="help"><?php echo wc_help_tip( __( 'Displays whether or not debug logging is enabled for this gateway.', 'woocommerce-square' ) ); ?></td>
|
52 |
+
<td>
|
53 |
+
<?php if ( $gateway->debug_log() && $gateway->debug_checkout() ) : ?>
|
54 |
+
<?php echo esc_html__( 'Display at Checkout & Log', 'woocommerce-square' ); ?>
|
55 |
+
<?php elseif ( $gateway->debug_checkout() ) : ?>
|
56 |
+
<?php echo esc_html__( 'Display at Checkout', 'woocommerce-square' ); ?>
|
57 |
+
<?php elseif ( $gateway->debug_log() ) : ?>
|
58 |
+
<?php echo esc_html__( 'Save to Log', 'woocommerce-square' ); ?>
|
59 |
+
<?php else : ?>
|
60 |
+
<?php echo esc_html__( 'Off', 'woocommerce-square' ); ?>
|
61 |
+
<?php endif; ?>
|
62 |
+
</td>
|
63 |
+
</tr>
|
64 |
+
|
65 |
+
<?php
|
66 |
+
/**
|
67 |
+
* Payment Gateway System Status End Action.
|
68 |
+
*
|
69 |
+
* Allow actors to add info the end of the gateway system status section.
|
70 |
+
*
|
71 |
+
* @since 4.3.0
|
72 |
+
* @param \Payment_Gateway $gateway
|
73 |
+
*/
|
74 |
+
do_action( 'wc_payment_gateway_' . $gateway->get_id() . '_system_status_end', $gateway );
|
75 |
+
?>
|
76 |
+
|
77 |
+
</tbody>
|
78 |
+
|
79 |
+
</table>
|
includes/Framework/PaymentGateway/Admin/views/html-order-partial-capture.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wc-order-data-row wc-order-data-row-toggle sv-wc-payment-gateway-partial-capture wc-<?php echo esc_attr( $gateway->get_id_dasherized() ); ?>-partial-capture" style="display:none;">
|
2 |
+
<table class="wc-order-totals">
|
3 |
+
|
4 |
+
<tr>
|
5 |
+
<td class="label"><?php esc_html_e( 'Authorization total', 'woocommerce-square' ); ?>:</td>
|
6 |
+
<td class="total"><?php echo wc_price( $authorization_total, array( 'currency' => $order->get_currency() ) ); ?></td>
|
7 |
+
</tr>
|
8 |
+
<tr>
|
9 |
+
<td class="label"><?php esc_html_e( 'Amount already captured', 'woocommerce-square' ); ?>:</td>
|
10 |
+
<td class="total"><?php echo wc_price( $total_captured, array( 'currency' => $order->get_currency() ) ); ?></td>
|
11 |
+
</tr>
|
12 |
+
|
13 |
+
<?php if ( $remaining_total > 0 ) : ?>
|
14 |
+
<tr>
|
15 |
+
<td class="label"><?php esc_html_e( 'Remaining order total', 'woocommerce-square' ); ?>:</td>
|
16 |
+
<td class="total"><?php echo wc_price( $remaining_total, array( 'currency' => $order->get_currency() ) ); ?></td>
|
17 |
+
</tr>
|
18 |
+
<?php endif; ?>
|
19 |
+
|
20 |
+
<tr>
|
21 |
+
<td class="label"><label for="capture_amount"><?php esc_html_e( 'Capture amount', 'woocommerce-square' ); ?>:</label></td>
|
22 |
+
<td class="total">
|
23 |
+
<input type="text" class="text" id="capture_amount" name="capture_amount" class="wc_input_price" />
|
24 |
+
<div class="clear"></div>
|
25 |
+
</td>
|
26 |
+
</tr>
|
27 |
+
<tr>
|
28 |
+
<td class="label"><label for="capture_comment"><?php esc_html_e( 'Comment (optional):', 'woocommerce-square' ); ?></label></td>
|
29 |
+
<td class="total">
|
30 |
+
<input type="text" class="text" id="capture_comment" name="capture_comment" />
|
31 |
+
<div class="clear"></div>
|
32 |
+
</td>
|
33 |
+
</tr>
|
34 |
+
</table>
|
35 |
+
<div class="clear"></div>
|
36 |
+
<div class="capture-actions">
|
37 |
+
|
38 |
+
<?php $amount = '<span class="capture-amount">' . wc_price( 0, array( 'currency' => $order->get_currency() ) ) . '</span>'; ?>
|
39 |
+
|
40 |
+
<button type="button" class="button button-primary capture-action" disabled="disabled"><?php printf( esc_html__( 'Capture %s', 'woocommerce-square' ), $amount ); ?></button>
|
41 |
+
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce-square' ); ?></button>
|
42 |
+
|
43 |
+
<div class="clear"></div>
|
44 |
+
</div>
|
45 |
+
</div>
|
includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor-token.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $token_input_name = $input_name . '[' . $index . ']'; ?>
|
2 |
+
|
3 |
+
<tr class="token <?php echo ! $token['id'] ? 'new-token' : ''; ?>">
|
4 |
+
|
5 |
+
<?php foreach ( $fields as $field_id => $field ) : ?>
|
6 |
+
|
7 |
+
<?php $is_select = 'select' === $field['type'] && isset( $field['options'] ) && ! empty( $field['options'] ); ?>
|
8 |
+
|
9 |
+
<td class="token-<?php echo esc_attr( $field_id ); ?>">
|
10 |
+
|
11 |
+
<?php if ( ! $field['editable'] ) : ?>
|
12 |
+
|
13 |
+
<?php $display_value = $is_select && ! empty( $field['options'][ $token[ $field_id ] ] ) ? $field['options'][ $token[ $field_id ] ] : $token[ $field_id ]; ?>
|
14 |
+
|
15 |
+
<span class="token-<?php echo esc_attr( $field_id ); ?> token-attribute"><?php echo esc_attr( $display_value ); ?></span>
|
16 |
+
|
17 |
+
<input name="<?php echo esc_attr( $token_input_name ); ?>[<?php echo esc_attr( $field_id ); ?>]" value="<?php echo esc_attr( $token[ $field_id ] ); ?>" type="hidden" />
|
18 |
+
|
19 |
+
<?php elseif ( $is_select ) : ?>
|
20 |
+
|
21 |
+
<select name="<?php echo esc_attr( $token_input_name ); ?>[<?php echo esc_attr( $field_id ); ?>]">
|
22 |
+
|
23 |
+
<option value=""><?php esc_html_e( '-- Select an option --', 'woocommerce-square' ); ?></option>
|
24 |
+
|
25 |
+
<?php foreach ( $field['options'] as $value => $label ) : ?>
|
26 |
+
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $token[ $field_id ] ); ?>><?php echo esc_html( $label ); ?></option>
|
27 |
+
<?php endforeach; ?>
|
28 |
+
|
29 |
+
</select>
|
30 |
+
|
31 |
+
<?php else : ?>
|
32 |
+
|
33 |
+
<?php // Build the input attributes
|
34 |
+
$attributes = array();
|
35 |
+
|
36 |
+
foreach ( $field['attributes'] as $name => $value ) {
|
37 |
+
$attributes[] = esc_attr( $name ) . '="' . esc_attr( $value ) . '"';
|
38 |
+
} ?>
|
39 |
+
|
40 |
+
<input
|
41 |
+
name="<?php echo esc_attr( $token_input_name ); ?>[<?php echo esc_attr( $field_id ); ?>]"
|
42 |
+
value="<?php echo esc_attr( $token[ $field_id ] ); ?>"
|
43 |
+
type="text"
|
44 |
+
<?php echo implode( ' ', $attributes ); ?>
|
45 |
+
<?php echo $field['required'] ? 'required' : ''; ?>
|
46 |
+
/>
|
47 |
+
|
48 |
+
<?php endif; ?>
|
49 |
+
|
50 |
+
</td>
|
51 |
+
|
52 |
+
<?php endforeach; ?>
|
53 |
+
|
54 |
+
<input name="<?php echo esc_attr( $token_input_name ); ?>[type]" value="<?php echo esc_attr( $type ); ?>" type="hidden" />
|
55 |
+
|
56 |
+
<td class="token-default token-attribute">
|
57 |
+
<input name="<?php echo esc_attr( $input_name ); ?>_default" value="<?php echo esc_attr( $token['id'] ); ?>" type="radio" <?php checked( true, $token['default'] ); ?>/>
|
58 |
+
</td>
|
59 |
+
|
60 |
+
<?php // Token actions ?>
|
61 |
+
<td class="token-actions">
|
62 |
+
|
63 |
+
<?php foreach ( $actions as $action => $label ) : ?>
|
64 |
+
<button class="sv-wc-payment-gateway-token-action-button button" data-action="<?php echo esc_attr( $action ); ?>" data-token-id="<?php echo esc_attr( $token['id'] ); ?>" data-user-id="<?php echo esc_attr( $user_id ); ?>">
|
65 |
+
<?php echo esc_attr( $label ); ?>
|
66 |
+
</button>
|
67 |
+
<?php endforeach; ?>
|
68 |
+
|
69 |
+
</td>
|
70 |
+
|
71 |
+
</tr>
|
includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
|
3 |
+
<th><?php echo esc_html( $title ); ?></th>
|
4 |
+
|
5 |
+
<td class="forminp">
|
6 |
+
|
7 |
+
<table class="sv_wc_payment_gateway_token_editor widefat" data-gateway-id="<?php echo esc_attr( $id ); ?>">
|
8 |
+
|
9 |
+
<thead>
|
10 |
+
<tr>
|
11 |
+
|
12 |
+
<?php // Display a column for each token field
|
13 |
+
foreach ( $columns as $column_id => $column_title ) : ?>
|
14 |
+
<th class="token-<?php echo esc_attr( $column_id ); ?>"><?php echo esc_html( $column_title ); ?></th>
|
15 |
+
<?php endforeach; ?>
|
16 |
+
|
17 |
+
</tr>
|
18 |
+
</thead>
|
19 |
+
|
20 |
+
<tbody class="tokens">
|
21 |
+
|
22 |
+
<?php
|
23 |
+
/** Fire inside the payment gateway token editor.
|
24 |
+
*
|
25 |
+
* @since 4.3.0
|
26 |
+
* @param int $user_id the current user ID
|
27 |
+
*/
|
28 |
+
do_action( 'wc_payment_gateway_' . $id . '_token_editor_tokens', $user_id ); ?>
|
29 |
+
|
30 |
+
</tbody>
|
31 |
+
|
32 |
+
<tbody class="meta">
|
33 |
+
<tr class="no-tokens">
|
34 |
+
<td colspan="<?php echo count( $columns ); ?>"><?php esc_html_e( 'No saved payment tokens', 'woocommerce-square' ); ?></td>
|
35 |
+
</tr>
|
36 |
+
</tbody>
|
37 |
+
|
38 |
+
<?php // Editor actions
|
39 |
+
if ( ! empty( $actions ) ) : ?>
|
40 |
+
|
41 |
+
<tfoot>
|
42 |
+
<tr>
|
43 |
+
<th class="actions" colspan="<?php echo count( $columns ); ?>">
|
44 |
+
|
45 |
+
<?php foreach ( $actions as $action => $label ) : ?>
|
46 |
+
|
47 |
+
<?php $button_class = 'save' === $action ? 'button-primary' : 'button'; ?>
|
48 |
+
|
49 |
+
<button class="sv-wc-payment-gateway-token-editor-action-button <?php echo sanitize_html_class( $button_class ); ?>" data-action="<?php echo esc_attr( $action ); ?>" data-user-id="<?php echo esc_attr( $user_id ); ?>">
|
50 |
+
<?php echo esc_attr( $label ); ?>
|
51 |
+
</button>
|
52 |
+
|
53 |
+
<?php endforeach; ?>
|
54 |
+
|
55 |
+
</th>
|
56 |
+
</tr>
|
57 |
+
</tfoot>
|
58 |
+
|
59 |
+
<?php endif; ?>
|
60 |
+
|
61 |
+
</table>
|
62 |
+
|
63 |
+
</td>
|
64 |
+
|
65 |
+
</tr>
|
includes/Framework/PaymentGateway/Admin/views/html-user-profile-field-customer-id.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<th><label for="<?php echo esc_attr( $name ); ?>"><?php echo esc_html( $label ); ?></label></th>
|
3 |
+
<td>
|
4 |
+
<input class="regular-text" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value ); ?>" type="text" /><br/>
|
5 |
+
<span class="description"><?php esc_html_e( 'The gateway customer ID for the user. Only edit this if necessary.', 'woocommerce-square' ); ?></span>
|
6 |
+
</td>
|
7 |
+
</tr>
|
includes/Framework/PaymentGateway/Admin/views/html-user-profile-section.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div id="wc_payment_gateway_<?php echo esc_attr( $plugin_id ); ?>_user_settings" class="sv_wc_payment_gateway_user_settings woocommerce">
|
2 |
+
|
3 |
+
<h3><?php echo esc_html( $section_title ); ?></h3>
|
4 |
+
|
5 |
+
<?php if ( ! empty( $section_description ) ) : ?>
|
6 |
+
<p><?php echo wp_kses_post( $section_description ); ?></p>
|
7 |
+
<?php endif; ?>
|
8 |
+
|
9 |
+
<table class="form-table">
|
10 |
+
|
11 |
+
<tbody>
|
12 |
+
|
13 |
+
<?php
|
14 |
+
/** Fire inside the payment gateway user settings section.
|
15 |
+
*
|
16 |
+
* @since 4.3.0
|
17 |
+
* @param \WP_User $user the current user object
|
18 |
+
*/
|
19 |
+
do_action( 'wc_payment_gateway_' . $plugin_id . '_user_profile', $user ); ?>
|
20 |
+
|
21 |
+
</tbody>
|
22 |
+
|
23 |
+
</table>
|
24 |
+
|
25 |
+
</div>
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_API_Response.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
use WooCommerce\Square\Framework\Api\API_Response;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* WooCommerce Direct Payment Gateway API Response
|
10 |
+
*/
|
11 |
+
interface Payment_Gateway_API_Response extends API_Response {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Checks if the transaction was successful.
|
15 |
+
*
|
16 |
+
* @since 3.0.0
|
17 |
+
*
|
18 |
+
* @return bool true if approved, false otherwise
|
19 |
+
*/
|
20 |
+
public function transaction_approved();
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Returns true if the transaction was held, for instance due to AVS/CSC
|
25 |
+
* Fraud Settings. This indicates that the transaction was successful, but
|
26 |
+
* did not pass a fraud check and should be reviewed.
|
27 |
+
*
|
28 |
+
* @since 3.0.0
|
29 |
+
*
|
30 |
+
* @return bool true if the transaction was held, false otherwise
|
31 |
+
*/
|
32 |
+
public function transaction_held();
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the response status message, or null if there is no status message
|
37 |
+
* associated with this transaction.
|
38 |
+
*
|
39 |
+
* @since 3.0.0
|
40 |
+
*
|
41 |
+
* @return string status message
|
42 |
+
*/
|
43 |
+
public function get_status_message();
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Gets the response status code, or null if there is no status code
|
48 |
+
* associated with this transaction.
|
49 |
+
*
|
50 |
+
* @since 3.0.0
|
51 |
+
*
|
52 |
+
* @return string status code
|
53 |
+
*/
|
54 |
+
public function get_status_code();
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Gets the response transaction id, or null if there is no transaction id
|
59 |
+
* associated with this transaction.
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
*
|
63 |
+
* @return string transaction id
|
64 |
+
*/
|
65 |
+
public function get_transaction_id();
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Gets the payment type: 'credit-card', 'echeck', etc...
|
70 |
+
*
|
71 |
+
* @since 3.0.0
|
72 |
+
*
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function get_payment_type();
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Returns a message appropriate for a frontend user. This should be used
|
80 |
+
* to provide enough information to a user to allow them to resolve an
|
81 |
+
* issue on their own, but not enough to help nefarious folks fishing for
|
82 |
+
* info.
|
83 |
+
*
|
84 |
+
* @see Payment_Gateway_API_Response_Message_Helper
|
85 |
+
*
|
86 |
+
* @since 3.0.0
|
87 |
+
*
|
88 |
+
* @return string user message, if there is one
|
89 |
+
*/
|
90 |
+
public function get_user_message();
|
91 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api.php
ADDED
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* WooCommerce Direct Payment Gateway API
|
9 |
+
*/
|
10 |
+
interface Payment_Gateway_API {
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Perform a credit card authorization for the given order
|
15 |
+
*
|
16 |
+
* If the gateway does not support credit card authorizations, this method can be a no-op.
|
17 |
+
*
|
18 |
+
* @since 3.0.0
|
19 |
+
*
|
20 |
+
* @param \WC_Order $order the order
|
21 |
+
* @return Payment_Gateway_API_Response credit card charge response
|
22 |
+
* @throws \Exception network timeouts, etc
|
23 |
+
*/
|
24 |
+
public function credit_card_authorization( \WC_Order $order );
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Perform a credit card charge for the given order
|
29 |
+
*
|
30 |
+
* If the gateway does not support credit card charges, this method can be a no-op.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
*
|
34 |
+
* @param \WC_Order $order the order
|
35 |
+
* @return Payment_Gateway_API_Response credit card charge response
|
36 |
+
* @throws \Exception network timeouts, etc
|
37 |
+
*/
|
38 |
+
public function credit_card_charge( \WC_Order $order );
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Perform a credit card capture for a given authorized order
|
43 |
+
*
|
44 |
+
* If the gateway does not support credit card capture, this method can be a no-op.
|
45 |
+
*
|
46 |
+
* @since 3.0.0
|
47 |
+
*
|
48 |
+
* @param \WC_Order $order the order
|
49 |
+
* @return Payment_Gateway_API_Response credit card capture response
|
50 |
+
* @throws \Exception network timeouts, etc
|
51 |
+
*/
|
52 |
+
public function credit_card_capture( \WC_Order $order );
|
53 |
+
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Perform an eCheck debit (ACH transaction) for the given order
|
57 |
+
*
|
58 |
+
* If the gateway does not support check debits, this method can be a no-op.
|
59 |
+
*
|
60 |
+
* @since 3.0.0
|
61 |
+
*
|
62 |
+
* @param \WC_Order $order the order
|
63 |
+
* @return Payment_Gateway_API_Response check debit response
|
64 |
+
* @throws \Exception network timeouts, etc
|
65 |
+
*/
|
66 |
+
public function check_debit( \WC_Order $order );
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Perform a refund for the given order
|
71 |
+
*
|
72 |
+
* If the gateway does not support refunds, this method can be a no-op.
|
73 |
+
*
|
74 |
+
* @since 3.0.0
|
75 |
+
*
|
76 |
+
* @param \WC_Order $order order object
|
77 |
+
* @return Payment_Gateway_API_Response refund response
|
78 |
+
* @throws \Exception network timeouts, etc
|
79 |
+
*/
|
80 |
+
public function refund( \WC_Order $order );
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Perform a void for the given order
|
85 |
+
*
|
86 |
+
* If the gateway does not support voids, this method can be a no-op.
|
87 |
+
*
|
88 |
+
* @since 3.0.0
|
89 |
+
*
|
90 |
+
* @param \WC_Order $order order object
|
91 |
+
* @return Payment_Gateway_API_Response void response
|
92 |
+
* @throws \Exception network timeouts, etc
|
93 |
+
*/
|
94 |
+
public function void( \WC_Order $order );
|
95 |
+
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Creates a payment token for the given order
|
99 |
+
*
|
100 |
+
* If the gateway does not support tokenization, this method can be a no-op.
|
101 |
+
*
|
102 |
+
* @since 3.0.0
|
103 |
+
*
|
104 |
+
* @param \WC_Order $order the order
|
105 |
+
* @return Payment_Gateway_API_Create_Payment_Token_Response payment method tokenization response
|
106 |
+
* @throws \Exception network timeouts, etc
|
107 |
+
*/
|
108 |
+
public function tokenize_payment_method( \WC_Order $order );
|
109 |
+
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Updates a tokenized payment method.
|
113 |
+
*
|
114 |
+
* @since 3.0.0
|
115 |
+
*
|
116 |
+
* @param \WC_Order $order order object
|
117 |
+
* @return Payment_Gateway_API_Response
|
118 |
+
* @throws \Exception
|
119 |
+
*/
|
120 |
+
public function update_tokenized_payment_method( \WC_Order $order );
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Determines if this API supports updating tokenized payment methods.
|
125 |
+
*
|
126 |
+
* @see Payment_Gateway_API::update_tokenized_payment_method()
|
127 |
+
*
|
128 |
+
* @since 3.0.0
|
129 |
+
*
|
130 |
+
* @return bool
|
131 |
+
*/
|
132 |
+
public function supports_update_tokenized_payment_method();
|
133 |
+
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Removes the tokenized payment method. This method should not be invoked
|
137 |
+
* unless supports_remove_tokenized_payment_method() returns true, otherwise
|
138 |
+
* the results are undefined.
|
139 |
+
*
|
140 |
+
* @since 3.0.0
|
141 |
+
* @see Payment_Gateway_API::supports_remove_tokenized_payment_method()
|
142 |
+
*
|
143 |
+
* @param string $token the payment method token
|
144 |
+
* @param string $customer_id unique customer id for gateways that support it
|
145 |
+
* @return Payment_Gateway_API_Response remove tokenized payment method response
|
146 |
+
* @throws \Exception network timeouts, etc
|
147 |
+
*/
|
148 |
+
public function remove_tokenized_payment_method( $token, $customer_id );
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Returns true if this API supports a "remove tokenized payment method"
|
153 |
+
* request. If this method returns true, then remove_tokenized_payment_method()
|
154 |
+
* is considered safe to call.
|
155 |
+
*
|
156 |
+
* @since 3.0.0
|
157 |
+
* @see Payment_Gateway_API::remove_tokenized_payment_method()
|
158 |
+
*
|
159 |
+
* @return boolean true if this API supports a "remove tokenized payment method" request, false otherwise
|
160 |
+
*/
|
161 |
+
public function supports_remove_tokenized_payment_method();
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Returns all tokenized payment methods for the customer. This method
|
166 |
+
* should not be invoked unless supports_get_tokenized_payment_methods()
|
167 |
+
* return true, otherwise the results are undefined
|
168 |
+
*
|
169 |
+
* @since 3.0.0
|
170 |
+
* @see Payment_Gateway_API::supports_get_tokenized_payment_methods()
|
171 |
+
*
|
172 |
+
* @param string $customer_id unique customer id
|
173 |
+
* @return Payment_Gateway_API_Get_Tokenized_Payment_Methods_Response response containing any payment tokens for the customer
|
174 |
+
* @throws \Exception network timeouts, etc
|
175 |
+
*/
|
176 |
+
public function get_tokenized_payment_methods( $customer_id );
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Returns true if this API supports a "get tokenized payment methods"
|
181 |
+
* request. If this method returns true, then get_tokenized_payment_methods()
|
182 |
+
* is considered safe to call.
|
183 |
+
*
|
184 |
+
* @since 3.0.0
|
185 |
+
* @see Payment_Gateway_API::get_tokenized_payment_methods()
|
186 |
+
*
|
187 |
+
* @return boolean true if this API supports a "get tokenized payment methods" request, false otherwise
|
188 |
+
*/
|
189 |
+
public function supports_get_tokenized_payment_methods();
|
190 |
+
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Returns the most recent request object
|
194 |
+
*
|
195 |
+
* @since 3.0.0
|
196 |
+
*
|
197 |
+
* @return \WooCommerce\Square\Framework\Api\API_Request the most recent request object
|
198 |
+
*/
|
199 |
+
public function get_request();
|
200 |
+
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Returns the most recent response object
|
204 |
+
*
|
205 |
+
* @since 3.0.0
|
206 |
+
*
|
207 |
+
* @return Payment_Gateway_API_Response the most recent response object
|
208 |
+
*/
|
209 |
+
public function get_response();
|
210 |
+
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Returns the WC_Order object associated with the request, if any
|
214 |
+
*
|
215 |
+
* @since 3.0.0
|
216 |
+
*
|
217 |
+
* @return \WC_Order
|
218 |
+
*/
|
219 |
+
public function get_order();
|
220 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Authorization_Response.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* WooCommerce Direct Payment Gateway API Authorization Response
|
9 |
+
*
|
10 |
+
* Represents a Payment Gateway Credit Card Authorization response. This should
|
11 |
+
* also be used as the parent class for credit card charge (authorization +
|
12 |
+
* capture) responses.
|
13 |
+
*/
|
14 |
+
interface Payment_Gateway_API_Authorization_Response extends Payment_Gateway_API_Response {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* The authorization code is returned from the credit card processor to
|
18 |
+
* indicate that the charge will be paid by the card issuer.
|
19 |
+
*
|
20 |
+
* @since 3.0.0
|
21 |
+
*
|
22 |
+
* @return string credit card authorization code
|
23 |
+
*/
|
24 |
+
public function get_authorization_code();
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Returns the result of the AVS check.
|
29 |
+
*
|
30 |
+
* @since 3.0.0
|
31 |
+
*
|
32 |
+
* @return string result of the AVS check, if any
|
33 |
+
*/
|
34 |
+
public function get_avs_result();
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Returns the result of the CSC check.
|
39 |
+
*
|
40 |
+
* @since 3.0.0
|
41 |
+
*
|
42 |
+
* @return string result of CSC check
|
43 |
+
*/
|
44 |
+
public function get_csc_result();
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Returns true if the CSC check was successful.
|
49 |
+
*
|
50 |
+
* @since 3.0.0
|
51 |
+
*
|
52 |
+
* @return boolean true if the CSC check was successful
|
53 |
+
*/
|
54 |
+
public function csc_match();
|
55 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Create_Payment_Token_Response.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Response;
|
5 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Token;
|
6 |
+
|
7 |
+
defined( 'ABSPATH' ) or exit;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* WooCommerce Direct Payment Gateway API Create Payment Token Response
|
11 |
+
*/
|
12 |
+
interface Payment_Gateway_API_Create_Payment_Token_Response extends Payment_Gateway_API_Response {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Returns the payment token.
|
16 |
+
*
|
17 |
+
* @since 3.0.0
|
18 |
+
*
|
19 |
+
* @return Payment_Gateway_Payment_Token payment token
|
20 |
+
*/
|
21 |
+
public function get_payment_token();
|
22 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Customer_Response.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* WooCommerce Direct Payment Gateway API Customer Response
|
9 |
+
*/
|
10 |
+
interface Payment_Gateway_API_Customer_Response extends Payment_Gateway_API_Response {
|
11 |
+
/**
|
12 |
+
* Returns the customer ID.
|
13 |
+
*
|
14 |
+
* @since 3.0.0
|
15 |
+
*
|
16 |
+
* @return string customer ID returned by the gateway
|
17 |
+
*/
|
18 |
+
public function get_customer_id();
|
19 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Get_Tokenized_Payment_Methods_Response.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Token;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* WooCommerce Direct Payment Gateway API Create Payment Token Response
|
10 |
+
*/
|
11 |
+
interface Payment_Gateway_API_Get_Tokenized_Payment_Methods_Response extends Payment_Gateway_API_Response {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Returns any payment tokens.
|
15 |
+
*
|
16 |
+
* @since 3.0.0
|
17 |
+
*
|
18 |
+
* @return Payment_Gateway_Payment_Token[] array of Payment_Gateway_Payment_Token payment tokens, keyed by the token ID
|
19 |
+
*/
|
20 |
+
public function get_payment_tokens();
|
21 |
+
}
|
includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Response_Message_Helper.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Api;
|
3 |
+
|
4 |
+
defined( 'ABSPATH' ) or exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* WooCommerce Payment Gateway API Response Message Helper
|
8 |
+
*
|
9 |
+
* This utility class is meant to provide a standard set of error messages to be
|
10 |
+
* displayed to the customer during checkout.
|
11 |
+
*
|
12 |
+
* @since 3.0.0
|
13 |
+
*/
|
14 |
+
class Payment_Gateway_API_Response_Message_Helper {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Returns a message appropriate for a frontend user. This should be used
|
18 |
+
* to provide enough information to a user to allow them to resolve an
|
19 |
+
* issue on their own, but not enough to help nefarious folks fishing for
|
20 |
+
* info.
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
* @param string $message_id identifies the message to return
|
24 |
+
* @return string a user message
|
25 |
+
*/
|
26 |
+
public function get_user_message( $message_id ) {
|
27 |
+
|
28 |
+
$message = null;
|
29 |
+
|
30 |
+
switch ( $message_id ) {
|
31 |
+
|
32 |
+
// generic messages
|
33 |
+
case 'error': $message = esc_html__( 'An error occurred, please try again or try an alternate form of payment', 'woocommerce-square' ); break;
|
34 |
+
case 'decline': $message = esc_html__( 'We cannot process your order with the payment information that you provided. Please use a different payment account or an alternate payment method.', 'woocommerce-square' ); break;
|
35 |
+
case 'held_for_review': $message = esc_html__( 'This order is being placed on hold for review. Please contact us to complete the transaction.', 'woocommerce-square' ); break;
|
36 |
+
|
37 |
+
/* missing/invalid info */
|
38 |
+
|
39 |
+
// csc
|
40 |
+
case 'held_for_incorrect_csc': $message = esc_html__( 'This order is being placed on hold for review due to an incorrect card verification number. You may contact the store to complete the transaction.', 'woocommerce-square' ); break;
|
41 |
+
case 'csc_invalid': $message = esc_html__( 'The card verification number is invalid, please try again.', 'woocommerce-square' ); break;
|
42 |
+
case 'csc_missing': $message = esc_html__( 'Please enter your card verification number and try again.', 'woocommerce-square' ); break;
|
43 |
+
|
44 |
+
// card type
|
45 |
+
case 'card_type_not_accepted': $message = esc_html__( 'That card type is not accepted, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
46 |
+
case 'card_type_invalid': $message = esc_html__( 'The card type is invalid or does not correlate with the credit card number. Please try again or use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
47 |
+
case 'card_type_missing': $message = esc_html__( 'Please select the card type and try again.', 'woocommerce-square' ); break;
|
48 |
+
|
49 |
+
// card number
|
50 |
+
case 'card_number_type_invalid': $message = esc_html__( 'The card type is invalid or does not correlate with the credit card number. Please try again or use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
51 |
+
case 'card_number_invalid': $message = esc_html__( 'The card number is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
52 |
+
case 'card_number_missing': $message = esc_html__( 'Please enter your card number and try again.', 'woocommerce-square' ); break;
|
53 |
+
|
54 |
+
// card expiry
|
55 |
+
case 'card_expiry_invalid': $message = esc_html__( 'The card expiration date is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
56 |
+
case 'card_expiry_month_invalid': $message = esc_html__( 'The card expiration month is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
57 |
+
case 'card_expiry_year_invalid': $message = esc_html__( 'The card expiration year is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
58 |
+
case 'card_expiry_missing': $message = esc_html__( 'Please enter your card expiration date and try again.', 'woocommerce-square' ); break;
|
59 |
+
|
60 |
+
// bank
|
61 |
+
case 'bank_aba_invalid': $message_id = esc_html__( 'The bank routing number is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
62 |
+
case 'bank_account_number_invalid': $message_id = esc_html__( 'The bank account number is invalid, please re-enter and try again.', 'woocommerce-square' ); break;
|
63 |
+
|
64 |
+
/* decline reasons */
|
65 |
+
case 'card_expired': $message = esc_html__( 'The provided card is expired, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
66 |
+
case 'card_declined': $message = esc_html__( 'The provided card was declined, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
67 |
+
case 'insufficient_funds': $message = esc_html__( 'Insufficient funds in account, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
68 |
+
case 'card_inactive': $message = esc_html__( 'The card is inactivate or not authorized for card-not-present transactions, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
69 |
+
case 'credit_limit_reached': $message = esc_html__( 'The credit limit for the card has been reached, please use an alternate card or other form of payment.', 'woocommerce-square' ); break;
|
70 |
+
case 'csc_mismatch': $message = esc_html__( 'The card verification number does not match. Please re-enter and try again.', 'woocommerce-square' ); break;
|
71 |
+
case 'avs_mismatch': $message = esc_html__( 'The provided address does not match the billing address for cardholder. Please verify the address and try again.', 'woocommerce-square' ); break;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Payment Gateway API Response User Message Filter.
|
76 |
+
*
|
77 |
+
* Allow actors to modify the error message returned to a user when a transaction
|
78 |
+
* has encountered an error and the admin has enabled the "show detailed
|
79 |
+
* decline messages" setting
|
80 |
+
*
|
81 |
+
* @since 3.0.0
|
82 |
+
* @param string $message message to show to user
|
83 |
+
* @param string $message_id machine code for the message, e.g. card_expired
|
84 |
+
* @param Payment_Gateway_API_Response_Message_Helper $this instance
|
85 |
+
*/
|
86 |
+
return apply_filters( 'wc_payment_gateway_transaction_response_user_message', $message, $message_id, $this );
|
87 |
+
}
|
88 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Payment Gateway API class
|
4 |
+
*
|
5 |
+
* This file describes a class that provides an API to communicate
|
6 |
+
* with Apply Pay features.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api;
|
14 |
+
use WooCommerce\Square\Framework as SquareFramework;
|
15 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
16 |
+
|
17 |
+
defined( 'ABSPATH' ) or exit;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Sets up the Apple Pay API.
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
*/
|
24 |
+
class Payment_Gateway_Apple_Pay_API extends SquareFramework\Api\Base {
|
25 |
+
|
26 |
+
|
27 |
+
/** @var SquareFramework\PaymentGateway\Payment_Gateway the gateway instance */
|
28 |
+
protected $gateway;
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Constructs the class.
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
*
|
36 |
+
* @param SquareFramework\PaymentGateway\Payment_Gateway the gateway instance
|
37 |
+
*/
|
38 |
+
public function __construct( SquareFramework\PaymentGateway\Payment_Gateway $gateway ) {
|
39 |
+
|
40 |
+
$this->gateway = $gateway;
|
41 |
+
|
42 |
+
$this->request_uri = 'https://apple-pay-gateway-cert.apple.com/paymentservices/startSession';
|
43 |
+
|
44 |
+
$this->set_request_content_type_header( 'application/json' );
|
45 |
+
$this->set_request_accept_header( 'application/json' );
|
46 |
+
$this->set_response_handler( '\\WooCommerce\\Square\\Framework\\PaymentGateway\\ApplePay\\Api\\Payment_Gateway_Apple_Pay_API_Response' );
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Validates the Apple Pay merchant.
|
52 |
+
*
|
53 |
+
* @since 3.0.0
|
54 |
+
*
|
55 |
+
* @param string $url the validation URL
|
56 |
+
* @param string $merchant_id the merchant ID to validate
|
57 |
+
* @param string $domain_name the verified domain name
|
58 |
+
* @param string $display_name the merchant display name
|
59 |
+
* @return Payment_Gateway_Apple_Pay_API_Response the response object
|
60 |
+
* @throws \Exception
|
61 |
+
*/
|
62 |
+
public function validate_merchant( $url, $merchant_id, $domain_name, $display_name ) {
|
63 |
+
|
64 |
+
$this->request_uri = $url;
|
65 |
+
|
66 |
+
$request = $this->get_new_request();
|
67 |
+
|
68 |
+
$request->set_merchant_data( $merchant_id, $domain_name, $display_name );
|
69 |
+
|
70 |
+
return $this->perform_request( $request );
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Performs the request and return the parsed response.
|
76 |
+
*
|
77 |
+
* @since 3.0.0
|
78 |
+
*
|
79 |
+
* @param SquareFramework\Api\API_Request|object
|
80 |
+
* @return SquareFramework\Api\API_Response|object
|
81 |
+
* @throws \Exception
|
82 |
+
*/
|
83 |
+
protected function perform_request( $request ) {
|
84 |
+
|
85 |
+
// set PEM file cert for requests
|
86 |
+
add_action( 'http_api_curl', array( $this, 'set_cert_file' ) );
|
87 |
+
|
88 |
+
return parent::perform_request( $request );
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Sets the PEM file required for authentication.
|
94 |
+
*
|
95 |
+
* @internal
|
96 |
+
*
|
97 |
+
* @since 3.0.0
|
98 |
+
*
|
99 |
+
* @param resource $curl_handle
|
100 |
+
*/
|
101 |
+
public function set_cert_file( $curl_handle ) {
|
102 |
+
|
103 |
+
if ( ! $curl_handle ) {
|
104 |
+
return;
|
105 |
+
}
|
106 |
+
|
107 |
+
curl_setopt( $curl_handle, CURLOPT_SSLCERT, get_option( 'sv_wc_apple_pay_cert_path' ) );
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
/** Validation methods ****************************************************/
|
112 |
+
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Validates the post-parsed response.
|
116 |
+
*
|
117 |
+
* @since 3.0.0
|
118 |
+
*
|
119 |
+
* @return bool
|
120 |
+
*
|
121 |
+
* @throws \Exception
|
122 |
+
*/
|
123 |
+
protected function do_post_parse_response_validation() {
|
124 |
+
|
125 |
+
$response = $this->get_response();
|
126 |
+
|
127 |
+
if ( $response->get_status_code() && 200 !== $response->get_status_code() ) {
|
128 |
+
throw new \Exception( $response->get_status_message() );
|
129 |
+
}
|
130 |
+
|
131 |
+
return true;
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
/** Helper methods ********************************************************/
|
136 |
+
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Gets a new request object.
|
140 |
+
*
|
141 |
+
* @since 3.0.0
|
142 |
+
*
|
143 |
+
* @param array $type Optional. The desired request type
|
144 |
+
* @return Payment_Gateway_Apple_Pay_API_Request the request object
|
145 |
+
*/
|
146 |
+
protected function get_new_request( $type = array() ) {
|
147 |
+
|
148 |
+
return new Payment_Gateway_Apple_Pay_API_Request( $this->get_gateway() );
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Gets the gateway instance.
|
154 |
+
*
|
155 |
+
* @since 3.0.0
|
156 |
+
*
|
157 |
+
* @return Payment_Gateway
|
158 |
+
*/
|
159 |
+
protected function get_gateway() {
|
160 |
+
|
161 |
+
return $this->gateway;
|
162 |
+
}
|
163 |
+
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Gets the plugin instance.
|
167 |
+
*
|
168 |
+
* @since 3.0.0
|
169 |
+
*
|
170 |
+
* @return SquareFramework\PaymentGateway\Payment_Gateway_Plugin
|
171 |
+
*/
|
172 |
+
protected function get_plugin() {
|
173 |
+
|
174 |
+
return $this->get_gateway()->get_plugin();
|
175 |
+
}
|
176 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api_Request.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Request API class
|
4 |
+
*
|
5 |
+
* This file defines a class used to create the Request object
|
6 |
+
* for features related to Apple Pay.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api;
|
14 |
+
|
15 |
+
use WooCommerce\Square\Framework\Api\API_JSON_Request;
|
16 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
17 |
+
|
18 |
+
defined( 'ABSPATH' ) or exit;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The Apple Pay API request object.
|
22 |
+
*
|
23 |
+
* @since 3.0.0
|
24 |
+
*/
|
25 |
+
class Payment_Gateway_Apple_Pay_API_Request extends API_JSON_Request {
|
26 |
+
|
27 |
+
|
28 |
+
/** @var Payment_Gateway $gateway the gateway instance */
|
29 |
+
protected $gateway;
|
30 |
+
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Constructs the request.
|
34 |
+
*
|
35 |
+
* @since 3.0.0
|
36 |
+
*
|
37 |
+
* @param Payment_Gateway $gateway the gateway instance
|
38 |
+
*/
|
39 |
+
public function __construct( Payment_Gateway $gateway ) {
|
40 |
+
|
41 |
+
$this->gateway = $gateway;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Sets the data for merchant validation.
|
47 |
+
*
|
48 |
+
* @since 3.0.0
|
49 |
+
*
|
50 |
+
* @param string $merchant_id the merchant ID to validate
|
51 |
+
* @param string $domain_name the verified domain name
|
52 |
+
* @param string $display_name the merchant display name
|
53 |
+
*/
|
54 |
+
public function set_merchant_data( $merchant_id, $domain_name, $display_name ) {
|
55 |
+
|
56 |
+
$data = array(
|
57 |
+
'merchantIdentifier' => $merchant_id,
|
58 |
+
'domainName' => str_replace( array( 'http://', 'https://' ), '', $domain_name ),
|
59 |
+
'displayName' => $display_name,
|
60 |
+
);
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Filters the data for merchant validation.
|
64 |
+
*
|
65 |
+
* @since 3.0.0
|
66 |
+
*
|
67 |
+
* @param array $data {
|
68 |
+
* The merchant data.
|
69 |
+
*
|
70 |
+
* @var string $merchantIdentifier the merchant ID
|
71 |
+
* @var string $domainName the verified domain name
|
72 |
+
* @var string $displayName the merchant display name
|
73 |
+
* }
|
74 |
+
* @param Payment_Gateway_Apple_Pay_API_Request the request object
|
75 |
+
*/
|
76 |
+
$this->data = apply_filters( 'sv_wc_apple_pay_api_merchant_data', $data, $this );
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Get the string representation of this response with any and all sensitive
|
82 |
+
* elements masked or removed.
|
83 |
+
*
|
84 |
+
* @since 3.0.0
|
85 |
+
* @see API_Response::to_string_safe()
|
86 |
+
*
|
87 |
+
* @return string
|
88 |
+
*/
|
89 |
+
public function to_string_safe() {
|
90 |
+
|
91 |
+
// mask the merchant ID
|
92 |
+
$string = str_replace( $this->data['merchantIdentifier'], str_repeat( '*', strlen( $this->data['merchantIdentifier'] ) ), $this->to_string() );
|
93 |
+
|
94 |
+
return $string;
|
95 |
+
}
|
96 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api_Response.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Response API class
|
4 |
+
*
|
5 |
+
* This file defines a class used to create the Response object
|
6 |
+
* for features related to Apple Pay.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api;
|
14 |
+
use WooCommerce\Square\Framework\Api\API_JSON_Response;
|
15 |
+
|
16 |
+
defined( 'ABSPATH' ) or exit;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* The Apple Pay API response object.
|
20 |
+
*
|
21 |
+
* @since 3.0.0
|
22 |
+
*/
|
23 |
+
class Payment_Gateway_Apple_Pay_API_Response extends API_JSON_Response {
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Gets the status code.
|
28 |
+
*
|
29 |
+
* @since 3.0.0
|
30 |
+
*
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function get_status_code() {
|
34 |
+
|
35 |
+
return $this->statusCode;
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Gets the status message.
|
41 |
+
*
|
42 |
+
* @since 3.0.0
|
43 |
+
*
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
public function get_status_message() {
|
47 |
+
|
48 |
+
return $this->statusMessage;
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Gets the validated merchant session.
|
54 |
+
*
|
55 |
+
* @since 3.0.0
|
56 |
+
*
|
57 |
+
* @return string|array
|
58 |
+
*/
|
59 |
+
public function get_merchant_session() {
|
60 |
+
|
61 |
+
return $this->raw_response_json;
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get the string representation of this response with any and all sensitive
|
67 |
+
* elements masked or removed.
|
68 |
+
*
|
69 |
+
* No strong indication from the Apple documentation that these _need_ to be
|
70 |
+
* masked, but they don't provide any useful info and only make the debug
|
71 |
+
* logs unnecessarily huge.
|
72 |
+
*
|
73 |
+
* @since 3.0.0
|
74 |
+
* @see SquareFramework\Api\API_Response::to_string_safe()
|
75 |
+
*
|
76 |
+
* @return string
|
77 |
+
*/
|
78 |
+
public function to_string_safe() {
|
79 |
+
|
80 |
+
$string = $this->to_string();
|
81 |
+
|
82 |
+
// mask the merchant session ID
|
83 |
+
$string = str_replace( $this->merchantSessionIdentifier, str_repeat( '*', 10 ), $string );
|
84 |
+
|
85 |
+
// mask the merchant ID
|
86 |
+
$string = str_replace( $this->merchantIdentifier, str_repeat( '*', 10 ), $string );
|
87 |
+
|
88 |
+
// mask the signature
|
89 |
+
$string = str_replace( $this->signature, str_repeat( '*', 10 ), $string );
|
90 |
+
|
91 |
+
return $string;
|
92 |
+
}
|
93 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Payment_Response.php
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Sync Completed Email class
|
4 |
+
*
|
5 |
+
* This file defines a class that describes Apple Pay's
|
6 |
+
* Payment Response object.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @since 3.0.0
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api;
|
13 |
+
use WooCommerce\Square\Framework\Api\API_JSON_Response;
|
14 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
15 |
+
|
16 |
+
defined( 'ABSPATH' ) or exit;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* The Apple Pay payment response object.
|
20 |
+
*
|
21 |
+
* @since 3.0.0
|
22 |
+
*/
|
23 |
+
class Payment_Gateway_Apple_Pay_Payment_Response extends API_JSON_Response {
|
24 |
+
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Gets the authorized payment data.
|
28 |
+
*
|
29 |
+
* @since 3.0.0
|
30 |
+
*
|
31 |
+
* @return array
|
32 |
+
*/
|
33 |
+
public function get_payment_data() {
|
34 |
+
|
35 |
+
return ! empty( $this->token->paymentData ) ? (array) $this->token->paymentData : array();
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Gets the authorization transaction ID.
|
41 |
+
*
|
42 |
+
* @since 3.0.0
|
43 |
+
*
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
public function get_transaction_id() {
|
47 |
+
|
48 |
+
return ! empty( $this->token->transactionIdentifier ) ? $this->token->transactionIdentifier : '';
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Gets the authorized card type.
|
54 |
+
*
|
55 |
+
* @since 3.0.0
|
56 |
+
*
|
57 |
+
* @return string
|
58 |
+
*/
|
59 |
+
public function get_card_type() {
|
60 |
+
|
61 |
+
$card_type = ! empty( $this->token->paymentMethod->network ) ? $this->token->paymentMethod->network : 'card';
|
62 |
+
|
63 |
+
return Payment_Gateway_Helper::normalize_card_type( $card_type );
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Gets the last four digits of the authorized card.
|
69 |
+
*
|
70 |
+
* @since 3.0.0
|
71 |
+
*
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
public function get_last_four() {
|
75 |
+
|
76 |
+
$last_four = '';
|
77 |
+
|
78 |
+
if ( ! empty( $this->token->paymentMethod->displayName ) ) {
|
79 |
+
$last_four = substr( $this->token->paymentMethod->displayName, -4 );
|
80 |
+
}
|
81 |
+
|
82 |
+
return $last_four;
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Gets the billing address.
|
88 |
+
*
|
89 |
+
* @since 3.0.0
|
90 |
+
*
|
91 |
+
* @return array
|
92 |
+
*/
|
93 |
+
public function get_billing_address() {
|
94 |
+
|
95 |
+
$address = ! empty( $this->response_data->billingContact ) ? $this->response_data->billingContact : null;
|
96 |
+
|
97 |
+
$billing_address = $this->prepare_address( $address );
|
98 |
+
|
99 |
+
// set the billing email
|
100 |
+
if ( ! empty( $this->response_data->shippingContact->emailAddress ) ) {
|
101 |
+
$billing_address['email'] = $this->shippingContact->emailAddress;
|
102 |
+
}
|
103 |
+
|
104 |
+
// set the billing phone number
|
105 |
+
if ( ! empty( $this->response_data->shippingContact->phoneNumber ) ) {
|
106 |
+
$billing_address['phone'] = $this->shippingContact->phoneNumber;
|
107 |
+
}
|
108 |
+
|
109 |
+
return $billing_address;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Gets the shipping address.
|
115 |
+
*
|
116 |
+
* @since 3.0.0
|
117 |
+
*
|
118 |
+
* @return array
|
119 |
+
*/
|
120 |
+
public function get_shipping_address() {
|
121 |
+
|
122 |
+
$address = ! empty( $this->response_data->shippingContact ) ? $this->response_data->shippingContact : null;
|
123 |
+
|
124 |
+
$shipping_address = $this->prepare_address( $address );
|
125 |
+
|
126 |
+
return $shipping_address;
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Prepare an address to WC formatting.
|
132 |
+
*
|
133 |
+
* @since 3.0.0
|
134 |
+
*
|
135 |
+
* @param \stdClass|object $contact the address to prepare
|
136 |
+
* @return array
|
137 |
+
*/
|
138 |
+
protected function prepare_address( $contact ) {
|
139 |
+
|
140 |
+
$address = array(
|
141 |
+
'first_name' => isset( $contact->givenName ) ? $contact->givenName : '',
|
142 |
+
'last_name' => isset( $contact->familyName ) ? $contact->familyName : '',
|
143 |
+
'address_1' => isset( $contact->addressLines[0] ) ? $contact->addressLines[0] : '',
|
144 |
+
'address_2' => '',
|
145 |
+
'city' => isset( $contact->locality ) ? $contact->locality : '',
|
146 |
+
'state' => isset( $contact->administrativeArea ) ? $contact->administrativeArea : '',
|
147 |
+
'postcode' => isset( $contact->postalCode ) ? $contact->postalCode : '',
|
148 |
+
'country' => isset( $contact->countryCode ) ? $contact->countryCode : '',
|
149 |
+
);
|
150 |
+
|
151 |
+
if ( ! empty( $contact->addressLines[1] ) ) {
|
152 |
+
$address['address_2'] = $contact->addressLines[1];
|
153 |
+
}
|
154 |
+
|
155 |
+
$address['country'] = strtoupper( $address['country'] );
|
156 |
+
|
157 |
+
return $address;
|
158 |
+
}
|
159 |
+
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Get the string representation of this response with any and all sensitive
|
163 |
+
* elements masked or removed.
|
164 |
+
*
|
165 |
+
* No strong indication from the Apple documentation that these _need_ to be
|
166 |
+
* masked, but they don't provide any useful info and only make the debug
|
167 |
+
* logs unnecessarily huge.
|
168 |
+
*
|
169 |
+
* @since 3.0.0
|
170 |
+
*
|
171 |
+
* @see WooCommerce\Square\Framework\Api\API_Response::to_string_safe()
|
172 |
+
*
|
173 |
+
* @return string
|
174 |
+
*/
|
175 |
+
public function to_string_safe() {
|
176 |
+
|
177 |
+
$string = $this->to_string();
|
178 |
+
|
179 |
+
if ( ! empty( $this->token->paymentData->data ) ) {
|
180 |
+
$string = str_replace( $this->token->paymentData->data, str_repeat( '*', 10 ), $string );
|
181 |
+
}
|
182 |
+
|
183 |
+
if ( ! empty( $this->token->paymentData->signature ) ) {
|
184 |
+
$string = str_replace( $this->token->paymentData->signature, str_repeat( '*', 10 ), $string );
|
185 |
+
}
|
186 |
+
|
187 |
+
return $string;
|
188 |
+
}
|
189 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay.php
ADDED
@@ -0,0 +1,1029 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Payment Gateway: Apple Pay class
|
4 |
+
*
|
5 |
+
* This file defines a class that is the starting point for
|
6 |
+
* Apple Pay related features, such as Apple Pay admin settings,
|
7 |
+
* processing payments through Apple Pay, initializing classes that
|
8 |
+
* load Apple Pay related assets, etc.
|
9 |
+
*
|
10 |
+
* @package WooCommerce Square
|
11 |
+
* @subpackage Apple Pay
|
12 |
+
* @since 3.0.0
|
13 |
+
*/
|
14 |
+
|
15 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay;
|
16 |
+
use WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api as ApplePayApi;
|
17 |
+
use WooCommerce\Square\Framework as SquareFramework;
|
18 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
19 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
20 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Plugin;
|
21 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
22 |
+
|
23 |
+
defined( 'ABSPATH' ) or exit;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Sets up Apple Pay support.
|
27 |
+
*
|
28 |
+
* @since 3.0.0
|
29 |
+
*/
|
30 |
+
class Payment_Gateway_Apple_Pay {
|
31 |
+
|
32 |
+
/** @var Payment_Gateway_Apple_Pay_Admin the admin instance */
|
33 |
+
protected $admin;
|
34 |
+
|
35 |
+
/** @var Payment_Gateway_Apple_Pay_Frontend the frontend instance */
|
36 |
+
protected $frontend;
|
37 |
+
|
38 |
+
/** @var Payment_Gateway_Apple_Pay_AJAX the AJAX instance */
|
39 |
+
protected $ajax;
|
40 |
+
|
41 |
+
/** @var SquareFramework\PaymentGateway\Payment_Gateway_Plugin the plugin instance */
|
42 |
+
protected $plugin;
|
43 |
+
|
44 |
+
/** @var ApplePayApi\Payment_Gateway_Apple_Pay_API the Apple Pay API */
|
45 |
+
protected $api;
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Constructs the class.
|
50 |
+
*
|
51 |
+
* @since 3.0.0
|
52 |
+
*
|
53 |
+
* @param Payment_Gateway_Plugin $plugin the plugin instance
|
54 |
+
*/
|
55 |
+
public function __construct( Payment_Gateway_Plugin $plugin ) {
|
56 |
+
|
57 |
+
$this->plugin = $plugin;
|
58 |
+
|
59 |
+
$this->init();
|
60 |
+
|
61 |
+
if ( $this->is_available() ) {
|
62 |
+
add_filter( 'woocommerce_customer_taxable_address', array( $this, 'set_customer_taxable_address' ) );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Initializes the Apple Pay handlers.
|
69 |
+
*
|
70 |
+
* @since 3.0.0
|
71 |
+
*/
|
72 |
+
protected function init() {
|
73 |
+
|
74 |
+
if ( is_admin() && ! wp_doing_ajax() ) {
|
75 |
+
$this->admin = new Payment_Gateway_Apple_Pay_Admin( $this );
|
76 |
+
} else {
|
77 |
+
$this->ajax = new Payment_Gateway_Apple_Pay_AJAX( $this );
|
78 |
+
$this->frontend = new Payment_Gateway_Apple_Pay_Frontend( $this->get_plugin(), $this );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Processes the payment after an Apple Pay authorization.
|
85 |
+
*
|
86 |
+
* This method creates a new order and calls the gateway for processing.
|
87 |
+
*
|
88 |
+
* @since 3.0.0
|
89 |
+
*
|
90 |
+
* @return array
|
91 |
+
* @throws \Exception
|
92 |
+
*/
|
93 |
+
public function process_payment() {
|
94 |
+
|
95 |
+
$order = null;
|
96 |
+
|
97 |
+
try {
|
98 |
+
|
99 |
+
$payment_response = $this->get_stored_payment_response();
|
100 |
+
|
101 |
+
if ( ! $payment_response ) {
|
102 |
+
throw new \Exception( __( 'Invalid payment response data', 'woocommerce-square' ) );
|
103 |
+
}
|
104 |
+
|
105 |
+
$this->log( sprintf( esc_html__( "Payment Response:\n %s", 'woocommerce-square' ) ), $payment_response->to_string_safe() . "\n" );
|
106 |
+
|
107 |
+
$order = Payment_Gateway_Apple_Pay_Orders::create_order( WC()->cart );
|
108 |
+
|
109 |
+
$order->set_payment_method( $this->get_processing_gateway() );
|
110 |
+
|
111 |
+
// if we got to this point, the payment was authorized by Apple Pay
|
112 |
+
// from here on out, it's up to the gateway to not screw things up.
|
113 |
+
$order->add_order_note( __( 'Apple Pay payment authorized.', 'woocommerce-square' ) );
|
114 |
+
|
115 |
+
$order->set_address( $payment_response->get_billing_address(), 'billing' );
|
116 |
+
$order->set_address( $payment_response->get_shipping_address(), 'shipping' );
|
117 |
+
$order->save();
|
118 |
+
|
119 |
+
// add Apple Pay response data to the order
|
120 |
+
add_filter( 'wc_payment_gateway_' . $this->get_processing_gateway()->get_id() . '_get_order', array( $this, 'add_order_data' ) );
|
121 |
+
|
122 |
+
if ( $this->is_test_mode() ) {
|
123 |
+
$result = $this->process_test_payment( $order );
|
124 |
+
} else {
|
125 |
+
$result = $this->get_processing_gateway()->process_payment( Order_Compatibility::get_prop( $order, 'id' ) );
|
126 |
+
}
|
127 |
+
|
128 |
+
if ( isset( $result['result'] ) && 'success' !== $result['result'] ) {
|
129 |
+
throw new \Exception( __( 'Gateway processing error.', 'woocommerce-square' ) );
|
130 |
+
}
|
131 |
+
|
132 |
+
if ( $user_id = $order->get_user_id() ) {
|
133 |
+
$this->update_customer_addresses( $user_id, $payment_response );
|
134 |
+
}
|
135 |
+
|
136 |
+
$this->clear_payment_data();
|
137 |
+
|
138 |
+
return $result;
|
139 |
+
|
140 |
+
} catch ( \Exception $e ) {
|
141 |
+
|
142 |
+
if ( $order ) {
|
143 |
+
|
144 |
+
$order->add_order_note( sprintf(
|
145 |
+
/** translators: Placeholders: %s - the error message */
|
146 |
+
esc_html__( 'Apple Pay payment failed. %s', 'woocommerce-square' ),
|
147 |
+
$e->getMessage()
|
148 |
+
) );
|
149 |
+
}
|
150 |
+
|
151 |
+
throw $e;
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Updates a customer's stored billing & shipping addresses based on the
|
158 |
+
* Apple Pay payment response.
|
159 |
+
*
|
160 |
+
* @since 3.0.0
|
161 |
+
*
|
162 |
+
* @param int $user_id WordPress user ID
|
163 |
+
* @param ApplePayApi\Payment_Gateway_Apple_Pay_Payment_Response $payment_response payment response object
|
164 |
+
*/
|
165 |
+
protected function update_customer_addresses( $user_id, ApplePayApi\Payment_Gateway_Apple_Pay_Payment_Response $payment_response ) {
|
166 |
+
|
167 |
+
foreach ( $payment_response->get_billing_address() as $key => $value ) {
|
168 |
+
update_user_meta( $user_id, 'billing_' . $key, $value );
|
169 |
+
}
|
170 |
+
|
171 |
+
$shipping_address = $payment_response->get_shipping_address();
|
172 |
+
|
173 |
+
if ( ! empty( $shipping_address['address_1'] ) ) {
|
174 |
+
|
175 |
+
foreach ( $payment_response->get_shipping_address() as $key => $value ) {
|
176 |
+
update_user_meta( $user_id, 'shipping_' . $key, $value );
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Simulates a successful gateway payment response.
|
184 |
+
*
|
185 |
+
* This provides an easy way for merchants to test that their certificates
|
186 |
+
* and other settings are correctly configured and communicating with Apple
|
187 |
+
* without processing actual payments to test.
|
188 |
+
*
|
189 |
+
* @since 3.0.0
|
190 |
+
*
|
191 |
+
* @param \WC_Order $order order object
|
192 |
+
* @return array
|
193 |
+
*/
|
194 |
+
protected function process_test_payment( \WC_Order $order ) {
|
195 |
+
|
196 |
+
$order->payment_complete();
|
197 |
+
|
198 |
+
WC()->cart->empty_cart();
|
199 |
+
|
200 |
+
return array(
|
201 |
+
'result' => 'success',
|
202 |
+
'redirect' => $this->get_processing_gateway()->get_return_url( $order ),
|
203 |
+
);
|
204 |
+
}
|
205 |
+
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Gets a single product payment request.
|
209 |
+
*
|
210 |
+
* @since 3.0.0
|
211 |
+
* @see Payment_Gateway_Apple_Pay::build_payment_request()
|
212 |
+
*
|
213 |
+
* @param \WC_Product $product product object
|
214 |
+
* @param bool $in_cart whether to generate a cart for this request
|
215 |
+
* @return array
|
216 |
+
* @throws \Exception
|
217 |
+
*/
|
218 |
+
public function get_product_payment_request( \WC_Product $product, $in_cart = false ) {
|
219 |
+
|
220 |
+
if ( ! is_user_logged_in() ) {
|
221 |
+
WC()->session->set_customer_session_cookie( true );
|
222 |
+
}
|
223 |
+
|
224 |
+
// no subscription products
|
225 |
+
if ( $this->get_plugin()->is_subscriptions_active() && \WC_Subscriptions_Product::is_subscription( $product ) ) {
|
226 |
+
throw new \Exception( __( 'Not available for subscription products.', 'woocommerce-square' ) );
|
227 |
+
}
|
228 |
+
|
229 |
+
// no pre-order "charge upon release" products
|
230 |
+
if ( $this->get_plugin()->is_pre_orders_active() && \WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) {
|
231 |
+
throw new \Exception( __( 'Not available for pre-order products that are set to charge upon release.', 'woocommerce-square' ) );
|
232 |
+
}
|
233 |
+
|
234 |
+
// only simple products
|
235 |
+
if ( ! $product->is_type( 'simple' ) ) {
|
236 |
+
throw new \Exception( __( 'Buy Now is only available for simple products', 'woocommerce-square' ) );
|
237 |
+
}
|
238 |
+
|
239 |
+
// if this product can't be purchased, bail
|
240 |
+
if ( ! $product->is_purchasable() || ! $product->is_in_stock() || ! $product->has_enough_stock( 1 ) ) {
|
241 |
+
throw new \Exception( __( 'Product is not available for purchase.', 'woocommerce-square' ) );
|
242 |
+
}
|
243 |
+
|
244 |
+
if ( $in_cart ) {
|
245 |
+
|
246 |
+
WC()->cart->empty_cart();
|
247 |
+
|
248 |
+
WC()->cart->add_to_cart( $product->get_id() );
|
249 |
+
|
250 |
+
$request = $this->get_cart_payment_request( WC()->cart );
|
251 |
+
|
252 |
+
} else {
|
253 |
+
|
254 |
+
$request = $this->build_payment_request( $product->get_price(), array( 'needs_shipping' => $product->needs_shipping() ) );
|
255 |
+
|
256 |
+
$stored_request = $this->get_stored_payment_request();
|
257 |
+
|
258 |
+
$stored_request['product_id'] = $product->get_id();
|
259 |
+
|
260 |
+
$this->store_payment_request( $stored_request );
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Filters the Apple Pay Buy Now JS payment request.
|
265 |
+
*
|
266 |
+
* @since 3.0.0
|
267 |
+
* @param array $request request data
|
268 |
+
* @param \WC_Product $product product object
|
269 |
+
*/
|
270 |
+
return apply_filters( 'sv_wc_apple_pay_buy_now_payment_request', $request, $product );
|
271 |
+
}
|
272 |
+
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Gets a payment request based on WooCommerce cart data.
|
276 |
+
*
|
277 |
+
* @since 3.0.0
|
278 |
+
* @see Payment_Gateway_Apple_Pay::build_payment_request()
|
279 |
+
*
|
280 |
+
* @param \WC_Cart $cart cart object
|
281 |
+
* @return array
|
282 |
+
* @throws \Exception
|
283 |
+
*/
|
284 |
+
public function get_cart_payment_request( \WC_Cart $cart ) {
|
285 |
+
|
286 |
+
if ( $this->get_plugin()->is_subscriptions_active() && \WC_Subscriptions_Cart::cart_contains_subscription() ) {
|
287 |
+
throw new \Exception( __( 'Cart contains subscriptions.', 'woocommerce-square' ) );
|
288 |
+
}
|
289 |
+
|
290 |
+
if ( $this->get_plugin()->is_pre_orders_active() && \WC_Pre_Orders_Cart::cart_contains_pre_order() ) {
|
291 |
+
throw new \Exception( __( 'Cart contains pre-orders.', 'woocommerce-square' ) );
|
292 |
+
}
|
293 |
+
|
294 |
+
if ( Plugin_Compatibility::is_wc_version_lt( '3.2' ) && ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
|
295 |
+
define( 'WOOCOMMERCE_CHECKOUT', true );
|
296 |
+
}
|
297 |
+
|
298 |
+
$cart->calculate_totals();
|
299 |
+
|
300 |
+
if ( count( WC()->shipping->get_packages() ) > 1 ) {
|
301 |
+
throw new \Exception( __( 'Apple Pay cannot be used for multiple shipments.', 'woocommerce-square' ) );
|
302 |
+
}
|
303 |
+
|
304 |
+
$args = array(
|
305 |
+
'line_totals' => $this->get_cart_totals( $cart ),
|
306 |
+
'needs_shipping' => $cart->needs_shipping(),
|
307 |
+
);
|
308 |
+
|
309 |
+
// build it!
|
310 |
+
$request = $this->build_payment_request( $cart->total, $args );
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Filters the Apple Pay cart JS payment request.
|
314 |
+
*
|
315 |
+
* @since 3.0.0
|
316 |
+
* @param array $args the cart JS payment request
|
317 |
+
* @param \WC_Cart $cart the cart object
|
318 |
+
*/
|
319 |
+
return apply_filters( 'sv_wc_apple_pay_cart_payment_request', $request, $cart );
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Recalculates the lines and totals for the current payment request.
|
325 |
+
*
|
326 |
+
* @since 3.0.0
|
327 |
+
*
|
328 |
+
* @return array
|
329 |
+
* @throws \Exception
|
330 |
+
*/
|
331 |
+
public function recalculate_totals() {
|
332 |
+
|
333 |
+
$payment_request = $this->get_stored_payment_request();
|
334 |
+
|
335 |
+
if ( empty( $payment_request ) ){
|
336 |
+
throw new \Exception( __( 'Payment request data is missing.', 'woocommerce-square' ) );
|
337 |
+
}
|
338 |
+
|
339 |
+
// if this is a single product request, make sure the cart gets populated
|
340 |
+
if ( ! empty( $payment_request['product_id'] ) && $product = wc_get_product( $payment_request['product_id'] ) ) {
|
341 |
+
$payment_request = $this->get_product_payment_request( $product, true );
|
342 |
+
}
|
343 |
+
|
344 |
+
if ( ! WC()->cart ) {
|
345 |
+
throw new \Exception( __( 'Cart data is missing.', 'woocommerce-square' ) );
|
346 |
+
}
|
347 |
+
|
348 |
+
$totals = $this->get_cart_totals( WC()->cart );
|
349 |
+
|
350 |
+
$payment_request['lineItems'] = $this->build_payment_request_lines( $totals );
|
351 |
+
$payment_request['shippingMethods'] = array();
|
352 |
+
|
353 |
+
$packages = WC()->shipping->get_packages();
|
354 |
+
|
355 |
+
if ( ! empty( $packages ) ) {
|
356 |
+
|
357 |
+
foreach ( $packages[0]['rates'] as $method ) {
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Filters a shipping method's description for the Apple Pay payment card.
|
361 |
+
*
|
362 |
+
* @since 3.0.0
|
363 |
+
*
|
364 |
+
* @param string $detail shipping method detail, such as delivery estimation
|
365 |
+
* @param object $method shipping method object
|
366 |
+
*/
|
367 |
+
$method_detail = apply_filters( 'wc_payment_gateway_apple_pay_shipping_method_detail', '', $method );
|
368 |
+
|
369 |
+
$payment_request['shippingMethods'][] = array(
|
370 |
+
'label' => $method->get_label(),
|
371 |
+
'detail' => $method_detail,
|
372 |
+
'amount' => $this->format_price( $method->cost ),
|
373 |
+
'identifier' => $method->id,
|
374 |
+
);
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
// reset the order total based on the new line items
|
379 |
+
$payment_request['total']['amount'] = $this->format_price( array_sum( wp_list_pluck( $payment_request['lineItems'], 'amount' ) ) );
|
380 |
+
|
381 |
+
// update the stored payment request session with the new line items & totals
|
382 |
+
$this->store_payment_request( $payment_request );
|
383 |
+
|
384 |
+
return $payment_request;
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
/**
|
389 |
+
* Gets the line totals for a cart.
|
390 |
+
*
|
391 |
+
* @since 3.0.0
|
392 |
+
* @see Payment_Gateway_Apple_Pay::build_payment_request_lines()
|
393 |
+
*
|
394 |
+
* @param \WC_Cart $cart cart object
|
395 |
+
* @return array
|
396 |
+
*/
|
397 |
+
protected function get_cart_totals( \WC_Cart $cart ) {
|
398 |
+
|
399 |
+
if ( Plugin_Compatibility::is_wc_version_lt( '3.2' ) && ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
|
400 |
+
define( 'WOOCOMMERCE_CHECKOUT', true );
|
401 |
+
}
|
402 |
+
|
403 |
+
$cart->calculate_totals();
|
404 |
+
|
405 |
+
return array(
|
406 |
+
'subtotal' => $cart->subtotal_ex_tax,
|
407 |
+
'discount' => $cart->get_cart_discount_total(),
|
408 |
+
'shipping' => $cart->shipping_total,
|
409 |
+
'fees' => $cart->fee_total,
|
410 |
+
'taxes' => $cart->tax_total + $cart->shipping_tax_total,
|
411 |
+
);
|
412 |
+
}
|
413 |
+
|
414 |
+
|
415 |
+
/**
|
416 |
+
* Builds a payment request for the Apple Pay JS.
|
417 |
+
*
|
418 |
+
* This contains all of the data necessary to complete a payment.
|
419 |
+
*
|
420 |
+
* @since 3.0.0
|
421 |
+
*
|
422 |
+
* @param float|int $amount amount to be charged by Apple Pay
|
423 |
+
* @param array $args {
|
424 |
+
* Optional. The payment request args.
|
425 |
+
*
|
426 |
+
* @type string $currency_code Payment currency code. Defaults to the shop currency.
|
427 |
+
* @type string $country_code Payment country code. Defaults to the shop base country.
|
428 |
+
* @type string $merchant_name Merchant name. Defaults to the shop name.
|
429 |
+
* @type array $merchant_capabilities merchant capabilities
|
430 |
+
* @type array $supported_networks supported networks or card types
|
431 |
+
* @type bool $needs_shipping whether the payment needs shipping
|
432 |
+
* @type array $line_totals request line totals. @see \Payment_Gateway_Apple_Pay::build_payment_request_lines()
|
433 |
+
* }
|
434 |
+
*
|
435 |
+
* @return array
|
436 |
+
*/
|
437 |
+
public function build_payment_request( $amount, $args = array() ) {
|
438 |
+
|
439 |
+
$args = wp_parse_args( $args, array(
|
440 |
+
'currency_code' => get_woocommerce_currency(),
|
441 |
+
'country_code' => get_option( 'woocommerce_default_country' ),
|
442 |
+
'merchant_name' => get_bloginfo( 'name', 'display' ),
|
443 |
+
'merchant_capabilities' => $this->get_capabilities(),
|
444 |
+
'supported_networks' => $this->get_supported_networks(),
|
445 |
+
'line_totals' => array(),
|
446 |
+
'needs_shipping' => false,
|
447 |
+
) );
|
448 |
+
|
449 |
+
// set the base required defaults
|
450 |
+
$request = array(
|
451 |
+
'currencyCode' => $args['currency_code'],
|
452 |
+
'countryCode' => substr( $args['country_code'], 0, 2 ),
|
453 |
+
'merchantCapabilities' => $args['merchant_capabilities'],
|
454 |
+
'supportedNetworks' => $args['supported_networks'],
|
455 |
+
'requiredBillingContactFields' => array( 'postalAddress' ),
|
456 |
+
'requiredShippingContactFields' => array(
|
457 |
+
'phone',
|
458 |
+
'email',
|
459 |
+
'name',
|
460 |
+
),
|
461 |
+
);
|
462 |
+
|
463 |
+
if ( $args['needs_shipping'] ) {
|
464 |
+
$request['requiredShippingContactFields'][] = 'postalAddress';
|
465 |
+
}
|
466 |
+
|
467 |
+
if ( is_array( $args['line_totals'] ) && ! empty( $args['line_totals'] ) ) {
|
468 |
+
$request['lineItems'] = $this->build_payment_request_lines( $args['line_totals'] );
|
469 |
+
}
|
470 |
+
|
471 |
+
// order total
|
472 |
+
$request['total'] = array(
|
473 |
+
'type' => 'final',
|
474 |
+
'label' => $args['merchant_name'],
|
475 |
+
'amount' => $this->format_price( $amount ),
|
476 |
+
);
|
477 |
+
|
478 |
+
$this->store_payment_request( $request );
|
479 |
+
|
480 |
+
// remove line item keys that are only useful for us later
|
481 |
+
if ( ! empty( $request['lineItems'] ) ) {
|
482 |
+
$request['lineItems'] = array_values( $request['lineItems'] );
|
483 |
+
}
|
484 |
+
|
485 |
+
return $request;
|
486 |
+
}
|
487 |
+
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Builds payment request lines for the Apple Pay JS.
|
491 |
+
*
|
492 |
+
* Apple guidelines prefer that the "lines" displayed on the Apple Pay card
|
493 |
+
* should be overall order totals, instead of listing actual product lines.
|
494 |
+
* This method standardizes the main breakdowns which are:
|
495 |
+
* + Subtotal
|
496 |
+
* + Discounts (represented as a single negative amount)
|
497 |
+
* + Shipping
|
498 |
+
* + Fees
|
499 |
+
* + Taxes
|
500 |
+
*
|
501 |
+
* @since 3.0.0
|
502 |
+
*
|
503 |
+
* @param array $totals {
|
504 |
+
* Payment line totals.
|
505 |
+
*
|
506 |
+
* @type float $subtotal items subtotal
|
507 |
+
* @type float $discount discounts total
|
508 |
+
* @type float $shipping shipping total
|
509 |
+
* @type float $fees fees total
|
510 |
+
* @type float $taxes tax total
|
511 |
+
* }
|
512 |
+
* @return array
|
513 |
+
*/
|
514 |
+
public function build_payment_request_lines( $totals ) {
|
515 |
+
|
516 |
+
$totals = wp_parse_args( $totals, array(
|
517 |
+
'subtotal' => 0.00,
|
518 |
+
'discount' => 0.00,
|
519 |
+
'shipping' => 0.00,
|
520 |
+
'fees' => 0.00,
|
521 |
+
'taxes' => 0.00,
|
522 |
+
) );
|
523 |
+
|
524 |
+
$lines = array();
|
525 |
+
|
526 |
+
// subtotal
|
527 |
+
if ( $totals['subtotal'] > 0 ) {
|
528 |
+
|
529 |
+
$lines['subtotal'] = array(
|
530 |
+
'type' => 'final',
|
531 |
+
'label' => __( 'Subtotal', 'woocommerce-square' ),
|
532 |
+
'amount' => $this->format_price( $totals['subtotal'] ),
|
533 |
+
);
|
534 |
+
}
|
535 |
+
|
536 |
+
// discounts
|
537 |
+
if ( $totals['discount'] > 0 ) {
|
538 |
+
|
539 |
+
$lines['discount'] = array(
|
540 |
+
'type' => 'final',
|
541 |
+
'label' => __( 'Discount', 'woocommerce-square' ),
|
542 |
+
'amount' => abs( $this->format_price( $totals['discount'] ) ) * -1,
|
543 |
+
);
|
544 |
+
}
|
545 |
+
|
546 |
+
// shipping
|
547 |
+
if ( $totals['shipping'] > 0 ) {
|
548 |
+
|
549 |
+
$lines['shipping'] = array(
|
550 |
+
'type' => 'final',
|
551 |
+
'label' => __( 'Shipping', 'woocommerce-square' ),
|
552 |
+
'amount' => $this->format_price( $totals['shipping'] ),
|
553 |
+
);
|
554 |
+
}
|
555 |
+
|
556 |
+
// fees
|
557 |
+
if ( $totals['fees'] > 0 ) {
|
558 |
+
|
559 |
+
$lines['fees'] = array(
|
560 |
+
'type' => 'final',
|
561 |
+
'label' => __( 'Fees', 'woocommerce-square' ),
|
562 |
+
'amount' => $this->format_price( $totals['fees'] ),
|
563 |
+
);
|
564 |
+
}
|
565 |
+
|
566 |
+
// taxes
|
567 |
+
if ( $totals['taxes'] > 0 ) {
|
568 |
+
|
569 |
+
$lines['taxes'] = array(
|
570 |
+
'type' => 'final',
|
571 |
+
'label' => __( 'Taxes', 'woocommerce-square' ),
|
572 |
+
'amount' => $this->format_price( $totals['taxes'] ),
|
573 |
+
);
|
574 |
+
}
|
575 |
+
|
576 |
+
return $lines;
|
577 |
+
}
|
578 |
+
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Formats a total price for use with Apple Pay JS.
|
582 |
+
*
|
583 |
+
* @since 3.0.0
|
584 |
+
*
|
585 |
+
* @param string|float $price the price to format
|
586 |
+
* @return string
|
587 |
+
*/
|
588 |
+
protected function format_price( $price ) {
|
589 |
+
|
590 |
+
return wc_format_decimal( $price, 2 );
|
591 |
+
}
|
592 |
+
|
593 |
+
|
594 |
+
/**
|
595 |
+
* Gets the stored payment request data.
|
596 |
+
*
|
597 |
+
* @since 3.0.0
|
598 |
+
*
|
599 |
+
* @return array
|
600 |
+
*/
|
601 |
+
public function get_stored_payment_request() {
|
602 |
+
|
603 |
+
return WC()->session->get( 'apple_pay_payment_request', array() );
|
604 |
+
}
|
605 |
+
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Gets the stored payment response data.
|
609 |
+
*
|
610 |
+
* @since 3.0.0
|
611 |
+
*
|
612 |
+
* @return false|ApplePayApi\Payment_Gateway_Apple_Pay_Payment_Response|false
|
613 |
+
*/
|
614 |
+
public function get_stored_payment_response() {
|
615 |
+
|
616 |
+
$response_data = WC()->session->get( 'apple_pay_payment_response', array() );
|
617 |
+
|
618 |
+
if ( ! empty( $response_data ) ) {
|
619 |
+
return new ApplePayApi\Payment_Gateway_Apple_Pay_Payment_Response( $response_data );
|
620 |
+
} else {
|
621 |
+
return false;
|
622 |
+
}
|
623 |
+
}
|
624 |
+
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Stores payment request data for later use.
|
628 |
+
*
|
629 |
+
* @since 3.0.0
|
630 |
+
*
|
631 |
+
* @param mixed|array $data
|
632 |
+
*/
|
633 |
+
public function store_payment_request( $data ) {
|
634 |
+
|
635 |
+
WC()->session->set( 'apple_pay_payment_request', $data );
|
636 |
+
}
|
637 |
+
|
638 |
+
|
639 |
+
/**
|
640 |
+
* Stores payment response data for later use.
|
641 |
+
*
|
642 |
+
* @since 3.0.0
|
643 |
+
*
|
644 |
+
* @param mixed|array $data
|
645 |
+
*/
|
646 |
+
public function store_payment_response( $data ) {
|
647 |
+
|
648 |
+
WC()->session->set( 'apple_pay_payment_response', $data );
|
649 |
+
}
|
650 |
+
|
651 |
+
|
652 |
+
/**
|
653 |
+
* Clears all payment request & response data from the session.
|
654 |
+
*
|
655 |
+
* @since 3.0.0
|
656 |
+
*/
|
657 |
+
public function clear_payment_data() {
|
658 |
+
|
659 |
+
unset( WC()->session->apple_pay_payment_request );
|
660 |
+
unset( WC()->session->apple_pay_payment_response );
|
661 |
+
unset( WC()->session->order_awaiting_payment );
|
662 |
+
}
|
663 |
+
|
664 |
+
|
665 |
+
/**
|
666 |
+
* Filters and sets the customer's taxable address.
|
667 |
+
*
|
668 |
+
* This is necessary because Apple Pay doesn't ever provide a billing
|
669 |
+
* address until after payment is complete. If the shop is set to calculate
|
670 |
+
* tax based on the billing address, we need to use the shipping address
|
671 |
+
* to at least get some rates for new customers.
|
672 |
+
*
|
673 |
+
* @internal
|
674 |
+
*
|
675 |
+
* @since 3.0.0
|
676 |
+
*
|
677 |
+
* @param array $address taxable address
|
678 |
+
* @return array
|
679 |
+
*/
|
680 |
+
public function set_customer_taxable_address( $address ) {
|
681 |
+
|
682 |
+
$billing_country = WC()->customer->get_billing_country();
|
683 |
+
|
684 |
+
// set to the shipping address provided by Apple Pay if:
|
685 |
+
// 1. shipping is available
|
686 |
+
// 2. billing is not available
|
687 |
+
// 3. taxes aren't configured to use the shop base
|
688 |
+
if ( WC()->customer->get_shipping_country() && ! $billing_country && $address[0] !== WC()->countries->get_base_country() ) {
|
689 |
+
|
690 |
+
$address = array(
|
691 |
+
WC()->customer->get_shipping_country(),
|
692 |
+
WC()->customer->get_shipping_state(),
|
693 |
+
WC()->customer->get_shipping_postcode(),
|
694 |
+
WC()->customer->get_shipping_city(),
|
695 |
+
);
|
696 |
+
}
|
697 |
+
|
698 |
+
return $address;
|
699 |
+
}
|
700 |
+
|
701 |
+
|
702 |
+
/**
|
703 |
+
* Allows the processing gateway to add Apple Pay details to the payment data.
|
704 |
+
*
|
705 |
+
* @internal
|
706 |
+
*
|
707 |
+
* @since 3.0.0
|
708 |
+
*
|
709 |
+
* @param \WC_Order $order the order object
|
710 |
+
* @return \WC_Order
|
711 |
+
*/
|
712 |
+
public function add_order_data( $order ) {
|
713 |
+
|
714 |
+
if ( $response = $this->get_stored_payment_response() ) {
|
715 |
+
$order = $this->get_processing_gateway()->get_order_for_apple_pay( $order, $response );
|
716 |
+
}
|
717 |
+
|
718 |
+
return $order;
|
719 |
+
}
|
720 |
+
|
721 |
+
|
722 |
+
/**
|
723 |
+
* Gets the Apple Pay API.
|
724 |
+
*
|
725 |
+
* @since 3.0.0
|
726 |
+
*
|
727 |
+
* @return Payment_Gateway_Apple_Pay_API
|
728 |
+
*/
|
729 |
+
public function get_api() {
|
730 |
+
|
731 |
+
if ( ! $this->api instanceof ApplePayApi\Payment_Gateway_Apple_Pay_API ) {
|
732 |
+
|
733 |
+
require_once( $this->get_plugin()->get_payment_gateway_framework_path() . '/apple-pay/api/class-sv-wc-payment-gateway-apple-pay-api.php');
|
734 |
+
require_once( $this->get_plugin()->get_payment_gateway_framework_path() . '/apple-pay/api/class-sv-wc-payment-gateway-apple-pay-api-request.php');
|
735 |
+
require_once( $this->get_plugin()->get_payment_gateway_framework_path() . '/apple-pay/api/class-sv-wc-payment-gateway-apple-pay-api-response.php');
|
736 |
+
|
737 |
+
$this->api = new ApplePayApi\Payment_Gateway_Apple_Pay_API( $this->get_processing_gateway() );
|
738 |
+
}
|
739 |
+
|
740 |
+
return $this->api;
|
741 |
+
}
|
742 |
+
|
743 |
+
|
744 |
+
/**
|
745 |
+
* Adds a log entry to the gateway's debug log.
|
746 |
+
*
|
747 |
+
* @since 3.0.0
|
748 |
+
*
|
749 |
+
* @param string $message the log message to add
|
750 |
+
*/
|
751 |
+
public function log( $message ) {
|
752 |
+
|
753 |
+
$gateway = $this->get_processing_gateway();
|
754 |
+
|
755 |
+
if ( ! $gateway ) {
|
756 |
+
return;
|
757 |
+
}
|
758 |
+
|
759 |
+
if ( $gateway->debug_log() ) {
|
760 |
+
$gateway->get_plugin()->log( sprintf( '[Apple Pay] %s', $message ), $gateway->get_id() );
|
761 |
+
}
|
762 |
+
}
|
763 |
+
|
764 |
+
|
765 |
+
/**
|
766 |
+
* Determines if Apple Pay is available.
|
767 |
+
*
|
768 |
+
* This does not indicate browser support or a user's ability, but rather
|
769 |
+
* that Apple Pay is properly configured and ready to be initiated by the
|
770 |
+
* Apple Pay JS.
|
771 |
+
*
|
772 |
+
* @since 3.0.0
|
773 |
+
*
|
774 |
+
* @return bool
|
775 |
+
*/
|
776 |
+
public function is_available() {
|
777 |
+
|
778 |
+
$is_available = wc_site_is_https() && $this->is_configured();
|
779 |
+
|
780 |
+
$is_available = $is_available && in_array( get_woocommerce_currency(), $this->get_accepted_currencies(), true );
|
781 |
+
|
782 |
+
/**
|
783 |
+
* Filters whether Apple Pay should be made available to users.
|
784 |
+
*
|
785 |
+
* @since 3.0.0
|
786 |
+
* @param bool $is_available
|
787 |
+
*/
|
788 |
+
return apply_filters( 'sv_wc_apple_pay_is_available', $is_available );
|
789 |
+
}
|
790 |
+
|
791 |
+
|
792 |
+
/**
|
793 |
+
* Determines if Apple Pay settings are properly configured.
|
794 |
+
*
|
795 |
+
* @since 3.0.0
|
796 |
+
*
|
797 |
+
* @return bool
|
798 |
+
*/
|
799 |
+
public function is_configured() {
|
800 |
+
|
801 |
+
if ( ! $this->get_processing_gateway() ) {
|
802 |
+
return false;
|
803 |
+
}
|
804 |
+
|
805 |
+
$is_configured = $this->is_enabled() && $this->get_merchant_id() && $this->get_processing_gateway()->is_enabled();
|
806 |
+
|
807 |
+
$is_configured = $is_configured && $this->is_cert_configured();
|
808 |
+
|
809 |
+
return $is_configured;
|
810 |
+
}
|
811 |
+
|
812 |
+
|
813 |
+
/**
|
814 |
+
* Determines if the certification path is set and valid.
|
815 |
+
*
|
816 |
+
* @since 3.0.0
|
817 |
+
*
|
818 |
+
* @return bool
|
819 |
+
*/
|
820 |
+
public function is_cert_configured() {
|
821 |
+
|
822 |
+
return is_readable( $this->get_cert_path() );
|
823 |
+
}
|
824 |
+
|
825 |
+
|
826 |
+
/**
|
827 |
+
* Determines if Apple Pay is enabled.
|
828 |
+
*
|
829 |
+
* @since 3.0.0
|
830 |
+
*
|
831 |
+
* @return bool
|
832 |
+
*/
|
833 |
+
public function is_enabled() {
|
834 |
+
|
835 |
+
return 'yes' === get_option( 'sv_wc_apple_pay_enabled' );
|
836 |
+
}
|
837 |
+
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Determines if test mode is enabled.
|
841 |
+
*
|
842 |
+
* @since 3.0.0
|
843 |
+
*
|
844 |
+
* @return bool
|
845 |
+
*/
|
846 |
+
public function is_test_mode() {
|
847 |
+
|
848 |
+
return 'yes' === get_option( 'sv_wc_apple_pay_test_mode' );
|
849 |
+
}
|
850 |
+
|
851 |
+
|
852 |
+
/**
|
853 |
+
* Gets the configured Apple merchant ID.
|
854 |
+
*
|
855 |
+
* @since 3.0.0
|
856 |
+
* @return string
|
857 |
+
*/
|
858 |
+
public function get_merchant_id() {
|
859 |
+
|
860 |
+
return get_option( 'sv_wc_apple_pay_merchant_id' );
|
861 |
+
}
|
862 |
+
|
863 |
+
|
864 |
+
/**
|
865 |
+
* Gets the certificate file path.
|
866 |
+
*
|
867 |
+
* @since 3.0.0
|
868 |
+
*
|
869 |
+
* @return string
|
870 |
+
*/
|
871 |
+
public function get_cert_path() {
|
872 |
+
|
873 |
+
return get_option( 'sv_wc_apple_pay_cert_path' );
|
874 |
+
}
|
875 |
+
|
876 |
+
|
877 |
+
/**
|
878 |
+
* Gets the currencies accepted by the gateway's Apple Pay integration.
|
879 |
+
*
|
880 |
+
* @since 3.0.0
|
881 |
+
*
|
882 |
+
* @return array
|
883 |
+
*/
|
884 |
+
public function get_accepted_currencies() {
|
885 |
+
|
886 |
+
$currencies = ( $this->get_processing_gateway() ) ? $this->get_processing_gateway()->get_apple_pay_currencies() : array();
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Filters the currencies accepted by the gateway's Apple Pay integration.
|
890 |
+
*
|
891 |
+
* @since 3.0.0
|
892 |
+
* @return array
|
893 |
+
*/
|
894 |
+
return apply_filters( 'sv_wc_apple_pay_accepted_currencies', $currencies );
|
895 |
+
}
|
896 |
+
|
897 |
+
|
898 |
+
/**
|
899 |
+
* Gets the gateway's Apple Pay capabilities.
|
900 |
+
*
|
901 |
+
* @since 3.0.0
|
902 |
+
*
|
903 |
+
* @return array
|
904 |
+
*/
|
905 |
+
public function get_capabilities() {
|
906 |
+
|
907 |
+
$valid_capabilities = array(
|
908 |
+
'supports3DS',
|
909 |
+
'supportsEMV',
|
910 |
+
'supportsCredit',
|
911 |
+
'supportsDebit',
|
912 |
+
);
|
913 |
+
|
914 |
+
$gateway_capabilities = ( $this->get_processing_gateway() ) ? $this->get_processing_gateway()->get_apple_pay_capabilities() : array();
|
915 |
+
|
916 |
+
$capabilities = array_intersect( $valid_capabilities, $gateway_capabilities );
|
917 |
+
|
918 |
+
/**
|
919 |
+
* Filters the gateway's Apple Pay capabilities.
|
920 |
+
*
|
921 |
+
* @since 3.0.0
|
922 |
+
*
|
923 |
+
* @param array $capabilities the gateway capabilities
|
924 |
+
* @param SquareFramework\PaymentGateway\ApplePay\Payment_Gateway_Apple_Pay $handler the Apple Pay handler
|
925 |
+
*/
|
926 |
+
return apply_filters( 'sv_wc_apple_pay_capabilities', array_values( $capabilities ), $this );
|
927 |
+
}
|
928 |
+
|
929 |
+
|
930 |
+
/**
|
931 |
+
* Gets the supported networks for Apple Pay.
|
932 |
+
*
|
933 |
+
* @since 3.0.0
|
934 |
+
*
|
935 |
+
* @return array
|
936 |
+
*/
|
937 |
+
public function get_supported_networks() {
|
938 |
+
|
939 |
+
$accepted_card_types = ( $this->get_processing_gateway() ) ? $this->get_processing_gateway()->get_card_types() : array();
|
940 |
+
|
941 |
+
$accepted_card_types = array_map( '\\WooCommerce\\Square\\Framework\\PaymentGateway\\Payment_Gateway_Helper::normalize_card_type', $accepted_card_types );
|
942 |
+
|
943 |
+
$valid_networks = array(
|
944 |
+
Payment_Gateway_Helper::CARD_TYPE_AMEX => 'amex',
|
945 |
+
Payment_Gateway_Helper::CARD_TYPE_DISCOVER => 'discover',
|
946 |
+
Payment_Gateway_Helper::CARD_TYPE_MASTERCARD => 'masterCard',
|
947 |
+
Payment_Gateway_Helper::CARD_TYPE_VISA => 'visa',
|
948 |
+
'privateLabel' => 'privateLabel', // ?
|
949 |
+
);
|
950 |
+
|
951 |
+
$networks = array_intersect_key( $valid_networks, array_flip( $accepted_card_types ) );
|
952 |
+
|
953 |
+
/**
|
954 |
+
* Filters the supported Apple Pay networks (card types).
|
955 |
+
*
|
956 |
+
* @since 3.0.0
|
957 |
+
*
|
958 |
+
* @param array $networks the supported networks
|
959 |
+
* @param SquareFramework\PaymentGateway\ApplePay\Payment_Gateway_Apple_Pay $handler the Apple Pay handler
|
960 |
+
*/
|
961 |
+
return apply_filters( 'sv_wc_apple_pay_supported_networks', array_values( $networks ), $this );
|
962 |
+
}
|
963 |
+
|
964 |
+
|
965 |
+
/**
|
966 |
+
* Gets the gateways that declare Apple Pay support.
|
967 |
+
*
|
968 |
+
* @since 3.0.0
|
969 |
+
*
|
970 |
+
* @return array the supporting gateways as `$gateway_id => Payment_Gateway`
|
971 |
+
*/
|
972 |
+
public function get_supporting_gateways() {
|
973 |
+
|
974 |
+
$available_gateways = $this->get_plugin()->get_gateways();
|
975 |
+
$supporting_gateways = array();
|
976 |
+
|
977 |
+
foreach ( $available_gateways as $key => $gateway ) {
|
978 |
+
|
979 |
+
if ( $gateway->supports_apple_pay() ) {
|
980 |
+
$supporting_gateways[ $gateway->get_id() ] = $gateway;
|
981 |
+
}
|
982 |
+
}
|
983 |
+
|
984 |
+
return $supporting_gateways;
|
985 |
+
}
|
986 |
+
|
987 |
+
|
988 |
+
/**
|
989 |
+
* Gets the gateway set to process Apple Pay transactions.
|
990 |
+
*
|
991 |
+
* @since 3.0.0
|
992 |
+
*
|
993 |
+
* @return SquareFramework\PaymentGateway\Payment_Gateway|null
|
994 |
+
*/
|
995 |
+
public function get_processing_gateway() {
|
996 |
+
|
997 |
+
$gateways = $this->get_supporting_gateways();
|
998 |
+
|
999 |
+
$gateway_id = get_option( 'sv_wc_apple_pay_payment_gateway' );
|
1000 |
+
|
1001 |
+
return isset( $gateways[ $gateway_id ] ) ? $gateways[ $gateway_id ] : null;
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
|
1005 |
+
/**
|
1006 |
+
* Gets the Apple Pay button style.
|
1007 |
+
*
|
1008 |
+
* @since 3.0.0
|
1009 |
+
*
|
1010 |
+
* @return string
|
1011 |
+
*/
|
1012 |
+
public function get_button_style() {
|
1013 |
+
|
1014 |
+
return get_option( 'sv_wc_apple_pay_button_style', 'black' );
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
|
1018 |
+
/**
|
1019 |
+
* Gets the gateway plugin instance.
|
1020 |
+
*
|
1021 |
+
* @since 3.0.0
|
1022 |
+
*
|
1023 |
+
* @return Payment_Gateway_Plugin
|
1024 |
+
*/
|
1025 |
+
public function get_plugin() {
|
1026 |
+
|
1027 |
+
return $this->plugin;
|
1028 |
+
}
|
1029 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Admin.php
ADDED
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Admin class
|
4 |
+
*
|
5 |
+
* This file defines a class that adds admin settings related
|
6 |
+
* to Apply Pay.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay;
|
14 |
+
|
15 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
16 |
+
|
17 |
+
defined( 'ABSPATH' ) or exit;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Sets up the Apple Pay settings screen.
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
*/
|
24 |
+
class Payment_Gateway_Apple_Pay_Admin {
|
25 |
+
|
26 |
+
|
27 |
+
/** @var Payment_Gateway_Apple_Pay the Apple Pay handler instance */
|
28 |
+
protected $handler;
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Construct the class.
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
*
|
36 |
+
* @param Payment_Gateway_Apple_Pay $handler main Apple Pay handler instance
|
37 |
+
*/
|
38 |
+
public function __construct( $handler ) {
|
39 |
+
|
40 |
+
$this->handler = $handler;
|
41 |
+
|
42 |
+
// add Apple Pay to the checkout settings sections
|
43 |
+
add_filter( 'woocommerce_get_sections_checkout', array( $this, 'add_settings_section' ), 99 );
|
44 |
+
|
45 |
+
// output the settings
|
46 |
+
add_action( 'woocommerce_settings_checkout', array( $this, 'add_settings' ) );
|
47 |
+
|
48 |
+
// render the special "static" gateway select
|
49 |
+
add_action( 'woocommerce_admin_field_static', array( $this, 'render_static_setting' ) );
|
50 |
+
|
51 |
+
// save the settings
|
52 |
+
add_action( 'woocommerce_settings_save_checkout', array( $this, 'save_settings' ) );
|
53 |
+
|
54 |
+
// add admin notices for configuration options that need attention
|
55 |
+
add_action( 'admin_footer', array( $this, 'add_admin_notices' ), 10 );
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Adds Apple Pay to the checkout settings sections.
|
61 |
+
*
|
62 |
+
* @internal
|
63 |
+
*
|
64 |
+
* @since 3.0.0
|
65 |
+
*
|
66 |
+
* @param array $sections the existing sections
|
67 |
+
* @return array
|
68 |
+
*/
|
69 |
+
public function add_settings_section( $sections ) {
|
70 |
+
|
71 |
+
$sections['apple-pay'] = __( 'Apple Pay', 'woocommerce-square' );
|
72 |
+
|
73 |
+
return $sections;
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Gets all of the combined settings.
|
79 |
+
*
|
80 |
+
* @since 3.0.0
|
81 |
+
*
|
82 |
+
* @return array $settings The combined settings.
|
83 |
+
*/
|
84 |
+
public function get_settings() {
|
85 |
+
|
86 |
+
$settings = array(
|
87 |
+
|
88 |
+
array(
|
89 |
+
'title' => __( 'Apple Pay', 'woocommerce-square' ),
|
90 |
+
'type' => 'title',
|
91 |
+
),
|
92 |
+
|
93 |
+
array(
|
94 |
+
'id' => 'sv_wc_apple_pay_enabled',
|
95 |
+
'title' => __( 'Enable / Disable', 'woocommerce-square' ),
|
96 |
+
'desc' => __( 'Accept Apple Pay', 'woocommerce-square' ),
|
97 |
+
'type' => 'checkbox',
|
98 |
+
'default' => 'no',
|
99 |
+
),
|
100 |
+
|
101 |
+
array(
|
102 |
+
'id' => 'sv_wc_apple_pay_display_locations',
|
103 |
+
'title' => __( 'Allow Apple Pay on', 'woocommerce-square' ),
|
104 |
+
'type' => 'multiselect',
|
105 |
+
'class' => 'wc-enhanced-select',
|
106 |
+
'css' => 'width: 350px;',
|
107 |
+
'options' => $this->get_display_location_options(),
|
108 |
+
'default' => array_keys( $this->get_display_location_options() ),
|
109 |
+
),
|
110 |
+
|
111 |
+
array(
|
112 |
+
'id' => 'sv_wc_apple_pay_button_style',
|
113 |
+
'title' => __( 'Button Style', 'woocommerce-square' ),
|
114 |
+
'type' => 'select',
|
115 |
+
'options' => array(
|
116 |
+
'black' => __( 'Black', 'woocommerce-square' ),
|
117 |
+
'white' => __( 'White', 'woocommerce-square' ),
|
118 |
+
'white-with-line' => __( 'White with outline', 'woocommerce-square' ),
|
119 |
+
),
|
120 |
+
'default' => 'black',
|
121 |
+
),
|
122 |
+
|
123 |
+
array(
|
124 |
+
'type' => 'sectionend',
|
125 |
+
),
|
126 |
+
);
|
127 |
+
|
128 |
+
$connection_settings = array(
|
129 |
+
array(
|
130 |
+
'title' => __( 'Connection Settings', 'woocommerce-square' ),
|
131 |
+
'type' => 'title',
|
132 |
+
),
|
133 |
+
|
134 |
+
array(
|
135 |
+
'id' => 'sv_wc_apple_pay_merchant_id',
|
136 |
+
'title' => __( 'Apple Merchant ID', 'woocommerce-square' ),
|
137 |
+
'type' => 'text',
|
138 |
+
'desc' => sprintf(
|
139 |
+
/** translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
140 |
+
__( 'This is found in your %1$sApple developer account%2$s', 'woocommerce-square' ),
|
141 |
+
'<a href="https://developer.apple.com" target="_blank">', '</a>'
|
142 |
+
),
|
143 |
+
),
|
144 |
+
|
145 |
+
array(
|
146 |
+
'id' => 'sv_wc_apple_pay_cert_path',
|
147 |
+
'title' => __( 'Certificate Path', 'woocommerce-square' ),
|
148 |
+
'type' => 'text',
|
149 |
+
'desc_tip' => __( 'The full system path to your certificate file from Apple. For security reasons you should store this outside of your web root.', 'woocommerce-square' ),
|
150 |
+
'desc' => sprintf(
|
151 |
+
/* translators: Placeholders: %s - the server's web root path */
|
152 |
+
__( 'For reference, your current web root path is: %s', 'woocommerce-square' ),
|
153 |
+
'<code>' . ABSPATH . '</code>'
|
154 |
+
),
|
155 |
+
),
|
156 |
+
);
|
157 |
+
|
158 |
+
$gateway_setting_id = 'sv_wc_apple_pay_payment_gateway';
|
159 |
+
$gateway_options = $this->get_gateway_options();
|
160 |
+
|
161 |
+
if ( 1 === count( $gateway_options ) ) {
|
162 |
+
|
163 |
+
$connection_settings[] = array(
|
164 |
+
'id' => $gateway_setting_id,
|
165 |
+
'title' => __( 'Processing Gateway', 'woocommerce-square' ),
|
166 |
+
'type' => 'static',
|
167 |
+
'value' => key( $gateway_options ),
|
168 |
+
'label' => current( $gateway_options ),
|
169 |
+
);
|
170 |
+
|
171 |
+
} else {
|
172 |
+
|
173 |
+
$connection_settings[] = array(
|
174 |
+
'id' => $gateway_setting_id,
|
175 |
+
'title' => __( 'Processing Gateway', 'woocommerce-square' ),
|
176 |
+
'type' => 'select',
|
177 |
+
'options' => $this->get_gateway_options(),
|
178 |
+
);
|
179 |
+
}
|
180 |
+
|
181 |
+
$connection_settings[] = array(
|
182 |
+
'id' => 'sv_wc_apple_pay_test_mode',
|
183 |
+
'title' => __( 'Test Mode', 'woocommerce-square' ),
|
184 |
+
'desc' => __( 'Enable to test Apple Pay functionality throughout your sites without processing real payments.', 'woocommerce-square' ),
|
185 |
+
'type' => 'checkbox',
|
186 |
+
'default' => 'no',
|
187 |
+
);
|
188 |
+
|
189 |
+
$connection_settings[] = array(
|
190 |
+
'type' => 'sectionend',
|
191 |
+
);
|
192 |
+
|
193 |
+
$settings = array_merge( $settings, $connection_settings );
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Filter the combined settings.
|
197 |
+
*
|
198 |
+
* @since 3.0.0
|
199 |
+
* @param array $settings The combined settings.
|
200 |
+
*/
|
201 |
+
return apply_filters( 'woocommerce_get_settings_apple_pay', $settings );
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Outputs the settings fields.
|
207 |
+
*
|
208 |
+
* @internal
|
209 |
+
*
|
210 |
+
* @since 3.0.0
|
211 |
+
*/
|
212 |
+
public function add_settings() {
|
213 |
+
global $current_section;
|
214 |
+
|
215 |
+
if ( 'apple-pay' === $current_section ) {
|
216 |
+
\WC_Admin_Settings::output_fields( $this->get_settings() );
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Saves the settings.
|
223 |
+
*
|
224 |
+
* @internal
|
225 |
+
*
|
226 |
+
* @since 3.0.0
|
227 |
+
*
|
228 |
+
* @global string $current_section The current settings section.
|
229 |
+
*/
|
230 |
+
public function save_settings() {
|
231 |
+
global $current_section;
|
232 |
+
|
233 |
+
// Output the general settings
|
234 |
+
if ( 'apple-pay' == $current_section ) {
|
235 |
+
|
236 |
+
\WC_Admin_Settings::save_fields( $this->get_settings() );
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Renders a static setting.
|
243 |
+
*
|
244 |
+
* This "setting" just displays simple text instead of a <select> with only
|
245 |
+
* one option.
|
246 |
+
*
|
247 |
+
* @since 3.0.0
|
248 |
+
*
|
249 |
+
* @param array $setting
|
250 |
+
*/
|
251 |
+
public function render_static_setting( $setting ) {
|
252 |
+
|
253 |
+
?>
|
254 |
+
|
255 |
+
<tr valign="top">
|
256 |
+
<th scope="row" class="titledesc">
|
257 |
+
<label for="<?php echo esc_attr( $setting['id'] ); ?>"><?php echo esc_html( $setting['title'] ); ?></label>
|
258 |
+
</th>
|
259 |
+
<td class="forminp forminp-<?php echo sanitize_title( $setting['type'] ) ?>">
|
260 |
+
<?php echo esc_html( $setting['label'] ); ?>
|
261 |
+
<input
|
262 |
+
name="<?php echo esc_attr( $setting['id'] ); ?>"
|
263 |
+
id="<?php echo esc_attr( $setting['id'] ); ?>"
|
264 |
+
value="<?php echo esc_html( $setting['value'] ); ?>"
|
265 |
+
type="hidden"
|
266 |
+
>
|
267 |
+
</td>
|
268 |
+
</tr><?php
|
269 |
+
}
|
270 |
+
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Adds admin notices for configuration options that need attention.
|
274 |
+
*
|
275 |
+
* @since 3.0.0
|
276 |
+
*/
|
277 |
+
public function add_admin_notices() {
|
278 |
+
|
279 |
+
// if the feature is not enabled, bail
|
280 |
+
if ( ! $this->handler->is_enabled() ) {
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
|
284 |
+
// if not on the settings screen, bail
|
285 |
+
if ( ! $this->is_settings_screen() ) {
|
286 |
+
return;
|
287 |
+
}
|
288 |
+
|
289 |
+
$errors = array();
|
290 |
+
|
291 |
+
// HTTPS notice
|
292 |
+
if ( ! wc_site_is_https() ) {
|
293 |
+
$errors[] = __( 'Your site must be served over HTTPS with a valid SSL certificate.', 'woocommerce-square' );
|
294 |
+
}
|
295 |
+
|
296 |
+
// Currency notice
|
297 |
+
if ( ! in_array( get_woocommerce_currency(), $this->handler->get_accepted_currencies(), true ) ) {
|
298 |
+
|
299 |
+
$accepted_currencies = $this->handler->get_accepted_currencies();
|
300 |
+
|
301 |
+
$errors[] = sprintf(
|
302 |
+
/* translators: Placeholders: %1$s - plugin name, %2$s - a currency/comma-separated list of currencies, %3$s - <a> tag, %4$s - </a> tag */
|
303 |
+
_n(
|
304 |
+
'Accepts payment in %1$s only. %2$sConfigure%3$s WooCommerce to accept %1$s to enable Apple Pay.',
|
305 |
+
'Accepts payment in one of %1$s only. %2$sConfigure%3$s WooCommerce to accept one of %1$s to enable Apple Pay.',
|
306 |
+
count( $accepted_currencies ),
|
307 |
+
'woocommerce-square'
|
308 |
+
),
|
309 |
+
'<strong>' . implode( ', ', $accepted_currencies ) . '</strong>',
|
310 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=general' ) ) . '">',
|
311 |
+
'</a>'
|
312 |
+
);
|
313 |
+
}
|
314 |
+
|
315 |
+
// bad cert config notice
|
316 |
+
// this first checks if the option has been set so the notice is not
|
317 |
+
// displayed without the user having the chance to set it.
|
318 |
+
if ( false !== $this->handler->get_cert_path() && ! $this->handler->is_cert_configured() ) {
|
319 |
+
|
320 |
+
$errors[] = sprintf(
|
321 |
+
/** translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
322 |
+
__( 'Your %1$sMerchant Identity Certificate%2$s cannot be found. Please check your path configuration.', 'woocommerce-square' ),
|
323 |
+
'<strong>', '</strong>'
|
324 |
+
);
|
325 |
+
}
|
326 |
+
|
327 |
+
if ( ! empty( $errors ) ) {
|
328 |
+
|
329 |
+
$message = '<strong>' . __( 'Apple Pay is disabled.', 'woocommerce-square' ) . '</strong>';
|
330 |
+
|
331 |
+
if ( 1 === count( $errors ) ) {
|
332 |
+
$message .= ' ' . current( $errors );
|
333 |
+
} else {
|
334 |
+
$message .= '<ul><li>' . implode( '</li><li>', $errors ) . '</li></ul>';
|
335 |
+
}
|
336 |
+
|
337 |
+
$this->handler->get_plugin()->get_admin_notice_handler()->add_admin_notice( $message, 'apple-pay-https-required', array(
|
338 |
+
'notice_class' => 'error',
|
339 |
+
'dismissible' => false,
|
340 |
+
) );
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Determines if the user is currently on the settings screen.
|
347 |
+
*
|
348 |
+
* @since 3.0.0
|
349 |
+
*
|
350 |
+
* @return bool
|
351 |
+
*/
|
352 |
+
protected function is_settings_screen() {
|
353 |
+
|
354 |
+
return 'wc-settings' === Square_Helper::get_request( 'page' ) && 'apple-pay' === Square_Helper::get_request( 'section' );
|
355 |
+
}
|
356 |
+
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Gets the available display location options.
|
360 |
+
*
|
361 |
+
* @since 3.0.0
|
362 |
+
*
|
363 |
+
* @return array
|
364 |
+
*/
|
365 |
+
protected function get_display_location_options() {
|
366 |
+
|
367 |
+
return array(
|
368 |
+
'product' => __( 'Single products', 'woocommerce-square' ),
|
369 |
+
'cart' => __( 'Cart', 'woocommerce-square' ),
|
370 |
+
'checkout' => __( 'Checkout', 'woocommerce-square' ),
|
371 |
+
);
|
372 |
+
}
|
373 |
+
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Gets the available gateway options.
|
377 |
+
*
|
378 |
+
* @since 3.0.0
|
379 |
+
*
|
380 |
+
* @return array
|
381 |
+
*/
|
382 |
+
protected function get_gateway_options() {
|
383 |
+
|
384 |
+
$gateways = $this->handler->get_supporting_gateways();
|
385 |
+
|
386 |
+
foreach ( $gateways as $id => $gateway ) {
|
387 |
+
$gateways[ $id ] = $gateway->get_method_title();
|
388 |
+
}
|
389 |
+
|
390 |
+
return $gateways;
|
391 |
+
}
|
392 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Ajax.php
ADDED
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay AJAX class
|
4 |
+
*
|
5 |
+
* This file defines a class that registers AJAX callbacks
|
6 |
+
* for payments through Apply Pay.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay;
|
14 |
+
|
15 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
16 |
+
|
17 |
+
defined( 'ABSPATH' ) or exit;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The Apple Pay AJAX handler.
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
*/
|
24 |
+
class Payment_Gateway_Apple_Pay_AJAX {
|
25 |
+
|
26 |
+
|
27 |
+
/** @var Payment_Gateway_Apple_Pay $handler the Apple Pay handler instance */
|
28 |
+
protected $handler;
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Constructs the class.
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
*
|
36 |
+
* @param Payment_Gateway_Apple_Pay $handler the Apple Pay handler instance
|
37 |
+
*/
|
38 |
+
public function __construct( Payment_Gateway_Apple_Pay $handler ) {
|
39 |
+
|
40 |
+
$this->handler = $handler;
|
41 |
+
|
42 |
+
if ( $this->get_handler()->is_available() ) {
|
43 |
+
|
44 |
+
add_action( 'wp_ajax_sv_wc_apple_pay_get_payment_request', array( $this, 'get_payment_request' ) );
|
45 |
+
add_action( 'wp_ajax_nopriv_sv_wc_apple_pay_get_payment_request', array( $this, 'get_payment_request' ) );
|
46 |
+
|
47 |
+
// validate the merchant
|
48 |
+
add_action( 'wp_ajax_sv_wc_apple_pay_validate_merchant', array( $this, 'validate_merchant' ) );
|
49 |
+
add_action( 'wp_ajax_nopriv_sv_wc_apple_pay_validate_merchant', array( $this, 'validate_merchant' ) );
|
50 |
+
|
51 |
+
// recalculate the payment request totals
|
52 |
+
add_action( 'wp_ajax_sv_wc_apple_pay_recalculate_totals', array( $this, 'recalculate_totals' ) );
|
53 |
+
add_action( 'wp_ajax_nopriv_sv_wc_apple_pay_recalculate_totals', array( $this, 'recalculate_totals' ) );
|
54 |
+
|
55 |
+
// process the payment
|
56 |
+
add_action( 'wp_ajax_sv_wc_apple_pay_process_payment', array( $this, 'process_payment' ) );
|
57 |
+
add_action( 'wp_ajax_nopriv_sv_wc_apple_pay_process_payment', array( $this, 'process_payment' ) );
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Gets a payment request for the specified type.
|
64 |
+
*
|
65 |
+
* @internal
|
66 |
+
*
|
67 |
+
* @since 3.0.0
|
68 |
+
*/
|
69 |
+
public function get_payment_request() {
|
70 |
+
|
71 |
+
$this->get_handler()->log( 'Getting payment request' );
|
72 |
+
|
73 |
+
try {
|
74 |
+
|
75 |
+
$request = $this->get_handler()->get_cart_payment_request( WC()->cart );
|
76 |
+
|
77 |
+
$this->get_handler()->log( sprintf( "Payment Request:\n %s", print_r( $request, true ) ) );
|
78 |
+
|
79 |
+
wp_send_json_success( wp_json_encode( $request ) );
|
80 |
+
|
81 |
+
} catch ( \Exception $e ) {
|
82 |
+
|
83 |
+
$this->get_handler()->log( sprintf( 'Could not build payment request. %s', $e->getMessage() ) );
|
84 |
+
|
85 |
+
wp_send_json_error( array(
|
86 |
+
'message' => $e->getMessage(),
|
87 |
+
'code' => $e->getCode(),
|
88 |
+
) );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Validates the merchant.
|
95 |
+
*
|
96 |
+
* @internal
|
97 |
+
*
|
98 |
+
* @since 3.0.0
|
99 |
+
*/
|
100 |
+
public function validate_merchant() {
|
101 |
+
|
102 |
+
$this->get_handler()->log( 'Validating merchant' );
|
103 |
+
|
104 |
+
check_ajax_referer( 'sv_wc_apple_pay_validate_merchant', 'nonce' );
|
105 |
+
|
106 |
+
$merchant_id = Square_Helper::get_post( 'merchant_id' );
|
107 |
+
$url = Square_Helper::get_post( 'url' );
|
108 |
+
|
109 |
+
try {
|
110 |
+
|
111 |
+
$response = $this->get_handler()->get_api()->validate_merchant( $url, $merchant_id, home_url(), get_bloginfo( 'name' ) );
|
112 |
+
|
113 |
+
wp_send_json_success( $response->get_merchant_session() );
|
114 |
+
|
115 |
+
} catch ( \Exception $e ) {
|
116 |
+
|
117 |
+
$this->get_handler()->log( sprintf( esc_html__( 'Could not validate merchant. %s', 'woocommerce-square' ), $e->getMessage() ) );
|
118 |
+
|
119 |
+
wp_send_json_error( array(
|
120 |
+
'message' => $e->getMessage(),
|
121 |
+
'code' => $e->getCode(),
|
122 |
+
) );
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Recalculates the totals for the current payment request.
|
129 |
+
*
|
130 |
+
* @internal
|
131 |
+
*
|
132 |
+
* @since 3.0.0
|
133 |
+
*/
|
134 |
+
public function recalculate_totals() {
|
135 |
+
|
136 |
+
$this->get_handler()->log( 'Recalculating totals' );
|
137 |
+
|
138 |
+
check_ajax_referer( 'sv_wc_apple_pay_recalculate_totals', 'nonce' );
|
139 |
+
|
140 |
+
try {
|
141 |
+
|
142 |
+
// if a contact is passed, set the customer address data
|
143 |
+
if ( isset( $_REQUEST['contact'] ) && is_array( $_REQUEST['contact'] ) ) {
|
144 |
+
|
145 |
+
$contact = wp_parse_args( $_REQUEST['contact'], array(
|
146 |
+
'administrativeArea' => null,
|
147 |
+
'countryCode' => null,
|
148 |
+
'locality' => null,
|
149 |
+
'postalCode' => null,
|
150 |
+
) );
|
151 |
+
|
152 |
+
$state = $contact['administrativeArea'];
|
153 |
+
$country = strtoupper( $contact['countryCode'] );
|
154 |
+
$city = $contact['locality'];
|
155 |
+
$postcode = $contact['postalCode'];
|
156 |
+
|
157 |
+
WC()->customer->set_shipping_city( $city );
|
158 |
+
WC()->customer->set_shipping_state( $state );
|
159 |
+
WC()->customer->set_shipping_country( $country );
|
160 |
+
WC()->customer->set_shipping_postcode( $postcode );
|
161 |
+
|
162 |
+
if ( $country ) {
|
163 |
+
WC()->customer->set_calculated_shipping( true );
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
167 |
+
$chosen_shipping_methods = ( $method = Square_Helper::get_request( 'method' ) ) ? array( wc_clean( $method ) ) : array();
|
168 |
+
|
169 |
+
WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
|
170 |
+
|
171 |
+
$payment_request = $this->get_handler()->recalculate_totals();
|
172 |
+
|
173 |
+
$data = array(
|
174 |
+
'shipping_methods' => $payment_request['shippingMethods'],
|
175 |
+
'line_items' => array_values( $payment_request['lineItems'] ),
|
176 |
+
'total' => $payment_request['total'],
|
177 |
+
);
|
178 |
+
|
179 |
+
$this->get_handler()->log( sprintf( "New totals:\n %s", print_r( $data, true ) ) );
|
180 |
+
|
181 |
+
wp_send_json_success( $data );
|
182 |
+
|
183 |
+
} catch ( \Exception $e ) {
|
184 |
+
|
185 |
+
$this->get_handler()->log( $e->getMessage() );
|
186 |
+
|
187 |
+
wp_send_json_error( array(
|
188 |
+
'message' => $e->getMessage(),
|
189 |
+
'code' => $e->getCode(),
|
190 |
+
) );
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Processes the payment after the Apple Pay authorization.
|
197 |
+
*
|
198 |
+
* @internal
|
199 |
+
*
|
200 |
+
* @since 3.0.0
|
201 |
+
*/
|
202 |
+
public function process_payment() {
|
203 |
+
|
204 |
+
$this->get_handler()->log( 'Processing payment' );
|
205 |
+
|
206 |
+
$type = Square_Helper::get_post( 'type' );
|
207 |
+
$response = stripslashes( Square_Helper::get_post( 'payment' ) );
|
208 |
+
|
209 |
+
$this->get_handler()->store_payment_response( $response );
|
210 |
+
|
211 |
+
try {
|
212 |
+
|
213 |
+
$result = $this->get_handler()->process_payment( $type, $response );
|
214 |
+
|
215 |
+
wp_send_json_success( $result );
|
216 |
+
|
217 |
+
} catch ( \Exception $e ) {
|
218 |
+
|
219 |
+
$this->get_handler()->log( sprintf( 'Payment failed. %s', $e->getMessage() ) );
|
220 |
+
|
221 |
+
wp_send_json_error( array(
|
222 |
+
'message' => $e->getMessage(),
|
223 |
+
'code' => $e->getCode(),
|
224 |
+
) );
|
225 |
+
}
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Gets the Apple Pay handler instance.
|
231 |
+
*
|
232 |
+
* @since 3.0.0
|
233 |
+
*
|
234 |
+
* @return Payment_Gateway_Apple_Pay
|
235 |
+
*/
|
236 |
+
protected function get_handler() {
|
237 |
+
|
238 |
+
return $this->handler;
|
239 |
+
}
|
240 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Frontend.php
ADDED
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Frontend Class
|
4 |
+
*
|
5 |
+
* This file defines a class responsible to load features
|
6 |
+
* related to Apply Pay on the front end.
|
7 |
+
* Features such as loading assets, rendering Apply Pay button, etc.
|
8 |
+
*
|
9 |
+
* @package WooCommerce Square
|
10 |
+
* @subpackage Apple Pay
|
11 |
+
* @since 3.0.0
|
12 |
+
*/
|
13 |
+
|
14 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay;
|
15 |
+
use WooCommerce\Square\Framework as SquareFramework;
|
16 |
+
|
17 |
+
defined( 'ABSPATH' ) or exit;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Sets up the Apple Pay front-end functionality.
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
*/
|
24 |
+
class Payment_Gateway_Apple_Pay_Frontend {
|
25 |
+
|
26 |
+
/** @var SquareFramework\PaymentGateway\Payment_Gateway_Plugin $plugin the gateway plugin instance */
|
27 |
+
protected $plugin;
|
28 |
+
|
29 |
+
/** @var Payment_Gateway_Apple_Pay $handler the Apple Pay handler instance */
|
30 |
+
protected $handler;
|
31 |
+
|
32 |
+
/** @var SquareFramework\PaymentGateway\Payment_Gateway $gateway the gateway instance */
|
33 |
+
protected $gateway;
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Constructs the class.
|
38 |
+
*
|
39 |
+
* @since 3.0.0
|
40 |
+
*
|
41 |
+
* @param SquareFramework\PaymentGateway\Payment_Gateway_Plugin $plugin the gateway plugin instance
|
42 |
+
* @param Payment_Gateway_Apple_Pay $handler the Apple Pay handler instance
|
43 |
+
*/
|
44 |
+
public function __construct( SquareFramework\PaymentGateway\Payment_Gateway_Plugin $plugin, Payment_Gateway_Apple_Pay $handler ) {
|
45 |
+
|
46 |
+
$this->plugin = $plugin;
|
47 |
+
|
48 |
+
$this->handler = $handler;
|
49 |
+
|
50 |
+
$this->gateway = $this->get_handler()->get_processing_gateway();
|
51 |
+
|
52 |
+
if ( $this->get_handler()->is_available() ) {
|
53 |
+
|
54 |
+
add_action( 'wp', array( $this, 'init' ) );
|
55 |
+
|
56 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Initializes the scripts and hooks.
|
63 |
+
*
|
64 |
+
* @since 3.0.0
|
65 |
+
*/
|
66 |
+
public function init() {
|
67 |
+
|
68 |
+
$locations = $this->get_display_locations();
|
69 |
+
|
70 |
+
if ( is_product() && in_array( 'product', $locations, true ) ) {
|
71 |
+
$this->init_product();
|
72 |
+
} else if ( is_cart() && in_array( 'cart', $locations, true ) ) {
|
73 |
+
$this->init_cart();
|
74 |
+
} else if ( is_checkout() && in_array( 'checkout', $locations, true ) ) {
|
75 |
+
$this->init_checkout();
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Gets the configured display locations.
|
82 |
+
*
|
83 |
+
* @since 3.0.0
|
84 |
+
*
|
85 |
+
* @return array
|
86 |
+
*/
|
87 |
+
protected function get_display_locations() {
|
88 |
+
|
89 |
+
return get_option( 'sv_wc_apple_pay_display_locations', array() );
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Enqueues the scripts.
|
95 |
+
*
|
96 |
+
* @since 3.0.0
|
97 |
+
*/
|
98 |
+
public function enqueue_scripts() {
|
99 |
+
|
100 |
+
wp_enqueue_style( 'wc-square-apple-pay', $this->get_plugin()->get_plugin_url() . '/assets/css/frontend/wc-square-payment-gateway-apple-pay.css', array(), $this->get_plugin()->get_version() ); // TODO: min
|
101 |
+
|
102 |
+
wp_enqueue_script( 'wc-square-apple-pay', $this->get_plugin()->get_plugin_url() . '/assets/js/frontend/wc-square-payment-gateway-apple-pay.min.js', array( 'jquery' ), $this->get_plugin()->get_version(), true );
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Filters the Apple Pay JS handler params.
|
106 |
+
*
|
107 |
+
* @since 3.0.0
|
108 |
+
* @param array $params the JS params
|
109 |
+
*/
|
110 |
+
$params = apply_filters( 'sv_wc_apple_pay_js_handler_params', array(
|
111 |
+
'gateway_id' => $this->get_gateway()->get_id(),
|
112 |
+
'gateway_id_dasherized' => $this->get_gateway()->get_id_dasherized(),
|
113 |
+
'merchant_id' => $this->get_handler()->get_merchant_id(),
|
114 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
115 |
+
'validate_nonce' => wp_create_nonce( 'sv_wc_apple_pay_validate_merchant' ),
|
116 |
+
'recalculate_totals_nonce' => wp_create_nonce( 'sv_wc_apple_pay_recalculate_totals' ),
|
117 |
+
'process_nonce' => wp_create_nonce( 'sv_wc_apple_pay_process_payment' ),
|
118 |
+
'generic_error' => __( 'An error occurred, please try again or try an alternate form of payment', 'woocommerce-square' ),
|
119 |
+
) );
|
120 |
+
|
121 |
+
wp_localize_script( 'wc-square-apple-pay', 'sv_wc_apple_pay_params', $params );
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Renders an Apple Pay button.
|
127 |
+
*
|
128 |
+
* @since 3.0.0
|
129 |
+
*/
|
130 |
+
public function render_button() {
|
131 |
+
|
132 |
+
$button_text = '';
|
133 |
+
$classes = array(
|
134 |
+
'sv-wc-apple-pay-button',
|
135 |
+
);
|
136 |
+
|
137 |
+
switch ( $this->get_handler()->get_button_style() ) {
|
138 |
+
|
139 |
+
case 'black':
|
140 |
+
$classes[] = 'apple-pay-button-black';
|
141 |
+
break;
|
142 |
+
|
143 |
+
case 'white':
|
144 |
+
$classes[] = 'apple-pay-button-white';
|
145 |
+
break;
|
146 |
+
|
147 |
+
case 'white-with-line':
|
148 |
+
$classes[] = 'apple-pay-button-white-with-line';
|
149 |
+
break;
|
150 |
+
}
|
151 |
+
|
152 |
+
// if on the single product page, add some text
|
153 |
+
if ( is_product() ) {
|
154 |
+
$classes[] = 'apple-pay-button-buy-now';
|
155 |
+
$button_text = __( 'Buy with', 'woocommerce-square' );
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( $button_text ) {
|
159 |
+
$classes[] = 'apple-pay-button-with-text';
|
160 |
+
}
|
161 |
+
|
162 |
+
echo '<button class="' . implode( ' ', array_map( 'sanitize_html_class', $classes ) ) . '" lang="' . esc_attr( substr( get_locale(), 0, 2 ) ) . '">';
|
163 |
+
|
164 |
+
if ( $button_text ) {
|
165 |
+
echo '<span class="text">' . esc_html( $button_text ) . '</span><span class="logo"></span>';
|
166 |
+
}
|
167 |
+
|
168 |
+
echo '</button>';
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Initializes Apple Pay on the single product page.
|
174 |
+
*
|
175 |
+
* @since 3.0.0
|
176 |
+
*/
|
177 |
+
public function init_product() {
|
178 |
+
|
179 |
+
$args = array();
|
180 |
+
|
181 |
+
try {
|
182 |
+
|
183 |
+
$product = wc_get_product( get_the_ID() );
|
184 |
+
|
185 |
+
if ( ! $product ) {
|
186 |
+
throw new \Exception( __( 'Product does not exist.', 'woocommerce-square' ) );
|
187 |
+
}
|
188 |
+
|
189 |
+
$payment_request = $this->get_handler()->get_product_payment_request( $product );
|
190 |
+
|
191 |
+
$args['payment_request'] = $payment_request;
|
192 |
+
|
193 |
+
} catch ( \Exception $e ) {
|
194 |
+
|
195 |
+
$this->get_handler()->log( sprintf( 'Could not initialize Apple Pay. %s', $e->getMessage() ) );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Filters the Apple Pay product handler args.
|
200 |
+
*
|
201 |
+
* @since 3.0.0
|
202 |
+
* @param array $args
|
203 |
+
*/
|
204 |
+
$args = apply_filters( 'sv_wc_apple_pay_product_handler_args', $args );
|
205 |
+
|
206 |
+
wc_enqueue_js( sprintf( 'window.sv_wc_apple_pay_handler = new Square_Apple_Pay_Product_Handler(%s);', wp_json_encode( $args ) ) );
|
207 |
+
|
208 |
+
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'render_button' ) );
|
209 |
+
}
|
210 |
+
|
211 |
+
|
212 |
+
/** Cart functionality ****************************************************/
|
213 |
+
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Initializes Apple Pay on the cart page.
|
217 |
+
*
|
218 |
+
* @since 3.0.0
|
219 |
+
*/
|
220 |
+
public function init_cart() {
|
221 |
+
|
222 |
+
$args = array();
|
223 |
+
|
224 |
+
try {
|
225 |
+
|
226 |
+
$payment_request = $this->get_handler()->get_cart_payment_request( WC()->cart );
|
227 |
+
|
228 |
+
$args['payment_request'] = $payment_request;
|
229 |
+
|
230 |
+
} catch ( \Exception $e ) {
|
231 |
+
|
232 |
+
$args['payment_request'] = false;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Filters the Apple Pay cart handler args.
|
237 |
+
*
|
238 |
+
* @since 3.0.0
|
239 |
+
* @param array $args
|
240 |
+
*/
|
241 |
+
$args = apply_filters( 'sv_wc_apple_pay_cart_handler_args', $args );
|
242 |
+
|
243 |
+
wc_enqueue_js( sprintf( 'window.sv_wc_apple_pay_handler = new Square_Apple_Pay_Cart_Handler(%s);', wp_json_encode( $args ) ) );
|
244 |
+
|
245 |
+
add_action( 'woocommerce_proceed_to_checkout', array( $this, 'render_button' ) );
|
246 |
+
}
|
247 |
+
|
248 |
+
|
249 |
+
/** Checkout functionality ************************************************/
|
250 |
+
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Initializes Apple Pay on the checkout page.
|
254 |
+
*
|
255 |
+
* @since 3.0.0
|
256 |
+
*/
|
257 |
+
public function init_checkout() {
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Filters the Apple Pay checkout handler args.
|
261 |
+
*
|
262 |
+
* @since 3.0.0
|
263 |
+
* @param array $args
|
264 |
+
*/
|
265 |
+
$args = apply_filters( 'sv_wc_apple_pay_checkout_handler_args', array() );
|
266 |
+
|
267 |
+
wc_enqueue_js( sprintf( 'window.sv_wc_apple_pay_handler = new Square_Apple_Pay_Checkout_Handler(%s);', wp_json_encode( $args ) ) );
|
268 |
+
|
269 |
+
if ( $this->get_plugin()->is_plugin_active( 'woocommerce-checkout-add-ons.php' ) ) {
|
270 |
+
add_action( 'woocommerce_review_order_before_payment', array( $this, 'render_button' ) );
|
271 |
+
} else {
|
272 |
+
add_action( 'woocommerce_before_checkout_form', array( $this, 'render_checkout_button' ), 15 );
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Renders the Apple Pay button for checkout.
|
279 |
+
*
|
280 |
+
* @since 3.0.0
|
281 |
+
*/
|
282 |
+
public function render_checkout_button() {
|
283 |
+
|
284 |
+
?>
|
285 |
+
|
286 |
+
<div class="sv-wc-apply-pay-checkout">
|
287 |
+
|
288 |
+
<?php /** translators: Phrase that preceeds the Apple Pay logo, i.e. "Pay with [logo]" */
|
289 |
+
$button_text = __( 'Pay with', 'woocommerce-square' );
|
290 |
+
|
291 |
+
$this->render_button(); ?>
|
292 |
+
|
293 |
+
<span class="divider">
|
294 |
+
<?php /** translators: "or" as in "Pay with Apple Pay [or] regular checkout" */
|
295 |
+
esc_html_e( 'or', 'woocommerce-square' ); ?>
|
296 |
+
</span>
|
297 |
+
|
298 |
+
</div>
|
299 |
+
|
300 |
+
<?php
|
301 |
+
}
|
302 |
+
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Gets the gateway instance.
|
306 |
+
*
|
307 |
+
* @since 3.0.0
|
308 |
+
*
|
309 |
+
* @return SquareFramework\PaymentGateway\Payment_Gateway
|
310 |
+
*/
|
311 |
+
protected function get_gateway() {
|
312 |
+
|
313 |
+
return $this->gateway;
|
314 |
+
}
|
315 |
+
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Gets the gateway plugin instance.
|
319 |
+
*
|
320 |
+
* @since 3.0.0
|
321 |
+
*
|
322 |
+
* @return SquareFramework\PaymentGateway\Payment_Gateway_Plugin
|
323 |
+
*/
|
324 |
+
protected function get_plugin() {
|
325 |
+
|
326 |
+
return $this->plugin;
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Gets the Apple Pay handler instance.
|
331 |
+
*
|
332 |
+
* @since 3.0.0
|
333 |
+
*
|
334 |
+
* @return Payment_Gateway_Apple_Pay
|
335 |
+
*/
|
336 |
+
protected function get_handler() {
|
337 |
+
|
338 |
+
return $this->handler;
|
339 |
+
}
|
340 |
+
}
|
includes/Framework/PaymentGateway/ApplePay/Payment_Gateway_Apple_Pay_Orders.php
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay Orders class
|
4 |
+
*
|
5 |
+
* This file defines a class that provides an API to modify orders
|
6 |
+
* created through Apple Pay.
|
7 |
+
*
|
8 |
+
* @package WooCommerce Square
|
9 |
+
* @subpackage Apple Pay
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\ApplePay;
|
14 |
+
|
15 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
16 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
17 |
+
|
18 |
+
defined( 'ABSPATH' ) or exit;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The Apple Pay order handler.
|
22 |
+
*
|
23 |
+
* @since 3.0.0
|
24 |
+
*/
|
25 |
+
class Payment_Gateway_Apple_Pay_Orders {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Creates an order from a cart.
|
29 |
+
*
|
30 |
+
* @since 3.0.0
|
31 |
+
*
|
32 |
+
* @param \WC_Cart $cart cart object
|
33 |
+
* @return \WC_Order|void
|
34 |
+
* @throws \Exception
|
35 |
+
* @throws \Exception
|
36 |
+
*/
|
37 |
+
public static function create_order( \WC_Cart $cart ) {
|
38 |
+
|
39 |
+
if ( Plugin_Compatibility::is_wc_version_lt( '3.2' ) && ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
|
40 |
+
define( 'WOOCOMMERCE_CHECKOUT', true );
|
41 |
+
}
|
42 |
+
|
43 |
+
$cart->calculate_totals();
|
44 |
+
|
45 |
+
try {
|
46 |
+
|
47 |
+
wc_transaction_query( 'start' );
|
48 |
+
|
49 |
+
$order_data = array(
|
50 |
+
'status' => apply_filters( 'woocommerce_default_order_status', 'pending' ),
|
51 |
+
'customer_id' => get_current_user_id(),
|
52 |
+
'cart_hash' => md5( wp_json_encode( wc_clean( $cart->get_cart_for_session() ) ) . $cart->total ),
|
53 |
+
'created_via' => 'apple_pay',
|
54 |
+
);
|
55 |
+
|
56 |
+
$order = self::get_order_object( $order_data );
|
57 |
+
|
58 |
+
foreach ( $cart->get_cart() as $cart_item_key => $item ) {
|
59 |
+
|
60 |
+
$args = array(
|
61 |
+
'variation' => $item['variation'],
|
62 |
+
'totals' => array(
|
63 |
+
'subtotal' => $item['line_subtotal'],
|
64 |
+
'subtotal_tax' => $item['line_subtotal_tax'],
|
65 |
+
'total' => $item['line_total'],
|
66 |
+
'tax' => $item['line_tax'],
|
67 |
+
'tax_data' => $item['line_tax_data']
|
68 |
+
),
|
69 |
+
);
|
70 |
+
|
71 |
+
if ( ! $order->add_product( $item['data'], $item['quantity'], $args ) ) {
|
72 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 525 ) );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
foreach ( $cart->get_coupons() as $code => $coupon ) {
|
77 |
+
|
78 |
+
if ( ! Order_Compatibility::add_coupon( $order, $code, $cart->get_coupon_discount_amount( $code ), $cart->get_coupon_discount_tax_amount( $code ) ) ) {
|
79 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 529 ) );
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
$chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() );
|
84 |
+
|
85 |
+
foreach ( WC()->shipping->get_packages() as $key => $package ) {
|
86 |
+
|
87 |
+
if ( isset( $package['rates'][ $chosen_methods[ $key ] ] ) ) {
|
88 |
+
|
89 |
+
$method = $package['rates'][ $chosen_methods[ $key ] ];
|
90 |
+
|
91 |
+
if ( ! Order_Compatibility::add_shipping( $order, $method ) ) {
|
92 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 527 ) );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
// add fees
|
98 |
+
foreach ( $cart->get_fees() as $key => $fee ) {
|
99 |
+
|
100 |
+
if ( ! Order_Compatibility::add_fee( $order, $fee ) ) {
|
101 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 526 ) );
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
$cart_taxes = Plugin_Compatibility::is_wc_version_gte( '3.2' ) ? $cart->get_cart_contents_taxes() : $cart->taxes;
|
106 |
+
$shipping_taxes = Plugin_Compatibility::is_wc_version_gte( '3.2' ) ? $cart->get_shipping_taxes() : $cart->shipping_taxes;
|
107 |
+
|
108 |
+
foreach ( array_keys( $cart_taxes + $shipping_taxes ) as $rate_id ) {
|
109 |
+
|
110 |
+
if ( $rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $rate_id ) {
|
111 |
+
|
112 |
+
if ( ! Order_Compatibility::add_tax( $order, $rate_id, $cart->get_tax_amount( $rate_id ), $cart->get_shipping_tax_amount( $rate_id ) ) ) {
|
113 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 526 ) );
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
wc_transaction_query( 'commit' );
|
119 |
+
|
120 |
+
$order->update_taxes();
|
121 |
+
|
122 |
+
$order->calculate_totals( false ); // false to skip recalculating taxes
|
123 |
+
|
124 |
+
do_action( 'woocommerce_checkout_update_order_meta', Order_Compatibility::get_prop( $order, 'id' ), array() );
|
125 |
+
|
126 |
+
return $order;
|
127 |
+
|
128 |
+
} catch ( \Exception $e ) {
|
129 |
+
|
130 |
+
wc_transaction_query( 'rollback' );
|
131 |
+
|
132 |
+
throw $e;
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Gets an order object for payment.
|
139 |
+
*
|
140 |
+
* @since 3.0.0
|
141 |
+
*
|
142 |
+
* @param array $order_data the order data
|
143 |
+
* @return \WC_Order
|
144 |
+
* @throws \Exception
|
145 |
+
*/
|
146 |
+
public static function get_order_object( $order_data ) {
|
147 |
+
|
148 |
+
$order_id = (int) WC()->session->get( 'order_awaiting_payment', 0 );
|
149 |
+
|
150 |
+
if ( $order_id && $order_data['cart_hash'] === get_post_meta( $order_id, '_cart_hash', true ) && ( $order = wc_get_order( $order_id ) ) && $order->has_status( array( 'pending', 'failed' ) ) ) {
|
151 |
+
|
152 |
+
$order_data['order_id'] = $order_id;
|
153 |
+
|
154 |
+
$order = wc_update_order( $order_data );
|
155 |
+
|
156 |
+
if ( is_wp_error( $order ) ) {
|
157 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 522 ) );
|
158 |
+
} else {
|
159 |
+
$order->remove_order_items();
|
160 |
+
}
|
161 |
+
|
162 |
+
} else {
|
163 |
+
|
164 |
+
$order = wc_create_order( $order_data );
|
165 |
+
|
166 |
+
if ( is_wp_error( $order ) ) {
|
167 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 520 ) );
|
168 |
+
} elseif ( false === $order ) {
|
169 |
+
throw new \Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-square' ), 521 ) );
|
170 |
+
}
|
171 |
+
|
172 |
+
// set the new order ID so it can be resumed in case of failure
|
173 |
+
WC()->session->set( 'order_awaiting_payment', Order_Compatibility::get_prop( $order, 'id' ) );
|
174 |
+
}
|
175 |
+
|
176 |
+
return $order;
|
177 |
+
}
|
178 |
+
}
|
includes/Framework/PaymentGateway/Handlers/Capture.php
ADDED
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Handlers;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
5 |
+
use WooCommerce\Square\Framework\Plugin_Compatibility;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Response;
|
8 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) or exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* The transaction capture handler.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Capture {
|
18 |
+
|
19 |
+
|
20 |
+
/** @var Payment_Gateway payment gateway instance */
|
21 |
+
private $gateway;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Capture constructor.
|
26 |
+
*
|
27 |
+
* @since 3.0.0
|
28 |
+
*
|
29 |
+
* @param Payment_Gateway $gateway payment gateway instance
|
30 |
+
*/
|
31 |
+
public function __construct( Payment_Gateway $gateway ) {
|
32 |
+
|
33 |
+
$this->gateway = $gateway;
|
34 |
+
|
35 |
+
// auto-capture on order status change if enabled
|
36 |
+
if ( $gateway->supports_credit_card_capture() && $gateway->is_paid_capture_enabled() ) {
|
37 |
+
add_action( 'woocommerce_order_status_changed', array( $this, 'maybe_capture_paid_order' ), 10, 3 );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Captures an order on status change to a "paid" status.
|
44 |
+
*
|
45 |
+
* @internal
|
46 |
+
*
|
47 |
+
* @since 3.0.0
|
48 |
+
*
|
49 |
+
* @param int $order_id order ID
|
50 |
+
* @param string $old_status status being changed
|
51 |
+
* @param string $new_status new order status
|
52 |
+
*/
|
53 |
+
public function maybe_capture_paid_order( $order_id, $old_status, $new_status ) {
|
54 |
+
|
55 |
+
$paid_statuses = wc_get_is_paid_statuses();
|
56 |
+
|
57 |
+
// bail if changing to a non-paid status or from a paid status
|
58 |
+
if ( ! in_array( $new_status, $paid_statuses, true ) || in_array( $old_status, $paid_statuses, true ) ) {
|
59 |
+
return;
|
60 |
+
}
|
61 |
+
|
62 |
+
$order = wc_get_order( $order_id );
|
63 |
+
|
64 |
+
if ( ! $order ) {
|
65 |
+
return;
|
66 |
+
}
|
67 |
+
|
68 |
+
$payment_method = Order_Compatibility::get_prop( $order, 'payment_method' );
|
69 |
+
|
70 |
+
if ( $payment_method !== $this->get_gateway()->get_id() ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
$this->maybe_perform_capture( $order );
|
75 |
+
}
|
76 |
+
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Perform a capture on an order if it can be captured.
|
80 |
+
*
|
81 |
+
* This acts as a wrapper for when the process should just bail without logging any errors or order notes, like when
|
82 |
+
* performing capture via bulk action.
|
83 |
+
*
|
84 |
+
* @since 3.0.0
|
85 |
+
*
|
86 |
+
* @param \WC_Order $order order object
|
87 |
+
* @param float|null $amount amount to capture
|
88 |
+
* @return bool
|
89 |
+
*/
|
90 |
+
public function maybe_perform_capture( \WC_Order $order, $amount = null ) {
|
91 |
+
|
92 |
+
// don't log any errors for for orders that can't be captured
|
93 |
+
if ( ! $this->order_can_be_captured( $order ) ) {
|
94 |
+
return false;
|
95 |
+
}
|
96 |
+
|
97 |
+
$result = $this->perform_capture( $order, $amount );
|
98 |
+
|
99 |
+
return ! empty( $result['success'] );
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Performs a credit card capture for an order.
|
105 |
+
*
|
106 |
+
* @since 3.0.0
|
107 |
+
*
|
108 |
+
* @param \WC_Order $order WooCommerce order object
|
109 |
+
* @param float|null $amount amount to capture
|
110 |
+
* @return array {
|
111 |
+
* Capture transaction results
|
112 |
+
*
|
113 |
+
* @type bool $success whether the capture was successful
|
114 |
+
* @type int $code result code
|
115 |
+
* @type string $message result message
|
116 |
+
* }
|
117 |
+
*/
|
118 |
+
public function perform_capture( \WC_Order $order, $amount = null ) {
|
119 |
+
|
120 |
+
$order = $this->get_gateway()->get_order_for_capture( $order, $amount );
|
121 |
+
|
122 |
+
try {
|
123 |
+
|
124 |
+
// notify if the gateway doesn't support captures when this is called directly
|
125 |
+
if ( ! $this->get_gateway()->supports_credit_card_capture() ) {
|
126 |
+
|
127 |
+
$message = "{$this->get_gateway()->get_method_title()} does not support payment captures";
|
128 |
+
|
129 |
+
Plugin_Compatibility::wc_doing_it_wrong( __METHOD__, $message, '3.0.0' );
|
130 |
+
|
131 |
+
throw new \Exception( $message, 500 );
|
132 |
+
}
|
133 |
+
|
134 |
+
// don't try to capture failed/cancelled/fully refunded transactions
|
135 |
+
if ( ! $this->is_order_ready_for_capture( $order ) ) {
|
136 |
+
throw new \Exception( __( 'Order cannot be captured', 'woocommerce-square' ), 400 );
|
137 |
+
}
|
138 |
+
|
139 |
+
// don't re-capture fully captured orders
|
140 |
+
if ( $this->has_order_authorization_expired( $order ) ) {
|
141 |
+
throw new \Exception( __( 'Transaction authorization has expired', 'woocommerce-square' ), 400 );
|
142 |
+
}
|
143 |
+
|
144 |
+
// don't re-capture fully captured orders
|
145 |
+
if ( $this->is_order_fully_captured( $order ) ) {
|
146 |
+
throw new \Exception( __( 'Transaction has already been fully captured', 'woocommerce-square' ), 400 );
|
147 |
+
}
|
148 |
+
|
149 |
+
// generally unavailable
|
150 |
+
if ( ! $this->order_can_be_captured( $order ) ) {
|
151 |
+
throw new \Exception( __( 'Transaction cannot be captured', 'woocommerce-square' ), 400 );
|
152 |
+
}
|
153 |
+
|
154 |
+
// attempt the capture
|
155 |
+
$response = $this->get_gateway()->get_api()->credit_card_capture( $order );
|
156 |
+
|
157 |
+
// bail early if the capture wasn't approved
|
158 |
+
if ( ! $response->transaction_approved() ) {
|
159 |
+
|
160 |
+
$this->do_capture_failed( $order, $response );
|
161 |
+
|
162 |
+
throw new \Exception( $response->get_status_code() . ' - ' . $response->get_status_message() );
|
163 |
+
}
|
164 |
+
|
165 |
+
$message = sprintf(
|
166 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - transaction amount. Definitions: Capture, as in capture funds from a credit card. */
|
167 |
+
esc_html__( '%1$s Capture of %2$s Approved', 'woocommerce-square' ),
|
168 |
+
$this->get_gateway()->get_method_title(),
|
169 |
+
wc_price( $order->capture->amount, array( 'currency' => Order_Compatibility::get_prop( $order, 'currency', 'view' ) ) )
|
170 |
+
);
|
171 |
+
|
172 |
+
// adds the transaction id (if any) to the order note
|
173 |
+
if ( $response->get_transaction_id() ) {
|
174 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
175 |
+
}
|
176 |
+
|
177 |
+
$order->add_order_note( $message );
|
178 |
+
|
179 |
+
// add the standard capture data to the order
|
180 |
+
$this->do_capture_success( $order, $response );
|
181 |
+
|
182 |
+
// if the original auth amount has been captured, complete payment
|
183 |
+
if ( $this->get_gateway()->get_order_meta( $order, 'capture_total' ) >= $order->get_total() ) {
|
184 |
+
|
185 |
+
// prevent stock from being reduced when payment is completed as this is done when the charge was authorized
|
186 |
+
add_filter( 'woocommerce_payment_complete_reduce_order_stock', '__return_false', 100 );
|
187 |
+
|
188 |
+
// complete the order
|
189 |
+
$order->payment_complete();
|
190 |
+
}
|
191 |
+
|
192 |
+
return array(
|
193 |
+
'success' => true,
|
194 |
+
'code' => 200,
|
195 |
+
'message' => $message,
|
196 |
+
);
|
197 |
+
|
198 |
+
} catch ( \Exception $exception ) {
|
199 |
+
|
200 |
+
// add an order note if this isn't a general error
|
201 |
+
if ( 500 !== $exception->getCode() ) {
|
202 |
+
|
203 |
+
$note_message = sprintf(
|
204 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - failure message. Definitions: "capture" as in capturing funds from a credit card. */
|
205 |
+
esc_html__( '%1$s Capture Failed: %2$s', 'woocommerce-square' ),
|
206 |
+
$this->get_gateway()->get_method_title(),
|
207 |
+
$exception->getMessage()
|
208 |
+
);
|
209 |
+
|
210 |
+
$order->add_order_note( $note_message );
|
211 |
+
}
|
212 |
+
|
213 |
+
return array(
|
214 |
+
'success' => false,
|
215 |
+
'code' => $exception->getCode(),
|
216 |
+
'message' => $exception->getMessage(),
|
217 |
+
);
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Adds the standard capture data to an order.
|
224 |
+
*
|
225 |
+
* @since 3.0.0
|
226 |
+
*
|
227 |
+
* @param \WC_Order $order the order object
|
228 |
+
* @param Payment_Gateway_API_Response $response transaction response
|
229 |
+
*/
|
230 |
+
public function do_capture_success( \WC_Order $order, Payment_Gateway_API_Response $response ) {
|
231 |
+
|
232 |
+
$total_captured = (float) $this->get_gateway()->get_order_meta( $order, 'capture_total' ) + (float) $order->capture->amount;
|
233 |
+
|
234 |
+
$this->get_gateway()->update_order_meta( $order, 'capture_total', Square_Helper::number_format( $total_captured ) );
|
235 |
+
$this->get_gateway()->update_order_meta( $order, 'charge_captured', $this->get_gateway()->supports_credit_card_partial_capture() && $this->get_gateway()->is_partial_capture_enabled() && $total_captured < (float) $this->get_order_capture_maximum( $order ) ? 'partial' : 'yes' );
|
236 |
+
|
237 |
+
// add capture transaction ID
|
238 |
+
if ( $response && $response->get_transaction_id() ) {
|
239 |
+
$this->get_gateway()->update_order_meta( $order, 'capture_trans_id', $response->get_transaction_id() );
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Lets gateways handle any specific capture failure results for the order.
|
246 |
+
*
|
247 |
+
* @since 3.0.0
|
248 |
+
*
|
249 |
+
* @param \WC_Order $order WooCommerce order object
|
250 |
+
* @param Payment_Gateway_API_Response $response API response object
|
251 |
+
*/
|
252 |
+
public function do_capture_failed( \WC_Order $order, Payment_Gateway_API_Response $response ) { }
|
253 |
+
|
254 |
+
|
255 |
+
/** Conditional Methods *******************************************************************************************/
|
256 |
+
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Determines if an order is eligible for capture.
|
260 |
+
*
|
261 |
+
* @since 3.0.0
|
262 |
+
*
|
263 |
+
* @param \WC_Order $order order object
|
264 |
+
* @return bool
|
265 |
+
*/
|
266 |
+
public function order_can_be_captured( \WC_Order $order ) {
|
267 |
+
|
268 |
+
// check whether the charge has already been captured by this gateway
|
269 |
+
if ( ! $this->is_order_ready_for_capture( $order ) || $this->is_order_fully_captured( $order ) ) {
|
270 |
+
return false;
|
271 |
+
}
|
272 |
+
|
273 |
+
// if for any reason the authorization can not be captured
|
274 |
+
if ( 'no' === $this->get_gateway()->get_order_meta( $order, 'auth_can_be_captured' ) ) {
|
275 |
+
return false;
|
276 |
+
}
|
277 |
+
|
278 |
+
// authorization hasn't already been captured, but has it expired?
|
279 |
+
return ! $this->has_order_authorization_expired( $order );
|
280 |
+
}
|
281 |
+
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Determines if an order is ready for capture.
|
285 |
+
*
|
286 |
+
* The base implementation of this method checks for a valid order status and that a transaction ID is set.
|
287 |
+
*
|
288 |
+
* @since 3.0.0
|
289 |
+
*
|
290 |
+
* @param \WC_Order $order order object
|
291 |
+
* @return bool
|
292 |
+
*/
|
293 |
+
public function is_order_ready_for_capture( \WC_Order $order ) {
|
294 |
+
|
295 |
+
return ! in_array( $order->get_status(), array( 'cancelled', 'refunded', 'failed' ), true ) && $this->get_gateway()->get_order_meta( $order, 'trans_id' );
|
296 |
+
}
|
297 |
+
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Determines if an order has been fully captured
|
301 |
+
*
|
302 |
+
* @since 3.0.0
|
303 |
+
*
|
304 |
+
* @param \WC_Order $order
|
305 |
+
* @return bool
|
306 |
+
*/
|
307 |
+
public function is_order_fully_captured( \WC_Order $order ) {
|
308 |
+
|
309 |
+
$captured = 'yes' === $this->get_gateway()->get_order_meta( $order, 'charge_captured' );
|
310 |
+
|
311 |
+
if ( ! $captured && $this->get_gateway()->supports_credit_card_partial_capture() && $this->get_gateway()->is_partial_capture_enabled() ) {
|
312 |
+
$captured = (float) $this->get_gateway()->get_order_meta( $order, 'capture_total' ) >= (float) $this->get_order_capture_maximum( $order );
|
313 |
+
}
|
314 |
+
|
315 |
+
return $captured;
|
316 |
+
}
|
317 |
+
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Determines if an order's authorization has expired.
|
321 |
+
*
|
322 |
+
* @since 3.0.0
|
323 |
+
*
|
324 |
+
* @param \WC_Order $order
|
325 |
+
* @return bool
|
326 |
+
*/
|
327 |
+
public function has_order_authorization_expired( \WC_Order $order ) {
|
328 |
+
|
329 |
+
$transaction_date = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'trans_date' );
|
330 |
+
|
331 |
+
$transaction_time = strtotime( $transaction_date );
|
332 |
+
|
333 |
+
return $transaction_date && floor( ( time() - $transaction_time ) / 3600 ) > $this->get_gateway()->get_authorization_time_window();
|
334 |
+
}
|
335 |
+
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Determines if an order's authorization has been captured, even partially.
|
339 |
+
*
|
340 |
+
* @since 3.0.0
|
341 |
+
*
|
342 |
+
* @param \WC_Order $order order object
|
343 |
+
* @return bool
|
344 |
+
*/
|
345 |
+
public function is_order_captured( \WC_Order $order ) {
|
346 |
+
|
347 |
+
return in_array( $this->get_gateway()->get_order_meta( $order, 'charge_captured' ), array( 'yes', 'partial' ), true );
|
348 |
+
}
|
349 |
+
|
350 |
+
|
351 |
+
/** Getter Methods ************************************************************************************************/
|
352 |
+
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Gets the maximum amount that can be captured from an order.
|
356 |
+
*
|
357 |
+
* Gateways can override this for an value above or below the order total.
|
358 |
+
* For instance, some processors allow capturing an amount a certain
|
359 |
+
* percentage higher than the payment total.
|
360 |
+
*
|
361 |
+
* @since 3.0.0
|
362 |
+
*
|
363 |
+
* @param \WC_Order $order WooCommerce order object
|
364 |
+
* @return float
|
365 |
+
*/
|
366 |
+
public function get_order_capture_maximum( \WC_Order $order ) {
|
367 |
+
|
368 |
+
return $this->get_order_authorization_amount( $order );
|
369 |
+
}
|
370 |
+
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Gets the amount originally authorized for an order.
|
374 |
+
*
|
375 |
+
* @since 3.0.0
|
376 |
+
*
|
377 |
+
* @param \WC_Order $order order object
|
378 |
+
* @return float
|
379 |
+
*/
|
380 |
+
public function get_order_authorization_amount( \WC_Order $order ) {
|
381 |
+
|
382 |
+
// if a specific auth amount was stored, use it
|
383 |
+
// otherwise, use the order total
|
384 |
+
$amount = $this->get_gateway()->get_order_meta( $order, 'authorization_amount' ) ?: $order->get_total();
|
385 |
+
|
386 |
+
return (float) $amount;
|
387 |
+
}
|
388 |
+
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Gets the payment gateway instance.
|
392 |
+
*
|
393 |
+
* @since 3.0.0
|
394 |
+
*
|
395 |
+
* @return Payment_Gateway
|
396 |
+
*/
|
397 |
+
protected function get_gateway() {
|
398 |
+
return $this->gateway;
|
399 |
+
}
|
400 |
+
}
|
includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Integrations;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Abstract Integration
|
10 |
+
*
|
11 |
+
* @since 3.0.0
|
12 |
+
*/
|
13 |
+
abstract class Payment_Gateway_Integration {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Payment_Gateway direct gateway instance */
|
17 |
+
protected $gateway;
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Bootstraps the class.
|
22 |
+
*
|
23 |
+
* @since 3.0.0
|
24 |
+
*
|
25 |
+
* @param Payment_Gateway $gateway direct gateway instance
|
26 |
+
*/
|
27 |
+
public function __construct( Payment_Gateway $gateway ) {
|
28 |
+
|
29 |
+
$this->gateway = $gateway;
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Return the gateway for the integration
|
35 |
+
*
|
36 |
+
* @since 3.0.0
|
37 |
+
* @return Payment_Gateway
|
38 |
+
*/
|
39 |
+
public function get_gateway() {
|
40 |
+
|
41 |
+
return $this->gateway;
|
42 |
+
}
|
43 |
+
}
|
includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Pre_Orders.php
ADDED
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Integrations;
|
4 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
5 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
6 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
7 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) or exit;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Pre-Orders Integration
|
13 |
+
*
|
14 |
+
* @since 3.0.0
|
15 |
+
*/
|
16 |
+
class Payment_Gateway_Integration_Pre_Orders extends Payment_Gateway_Integration {
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Bootstrap class
|
21 |
+
*
|
22 |
+
* @since 3.0.0
|
23 |
+
*
|
24 |
+
* @param Payment_Gateway|Payment_Gateway_Direct $gateway gateway object
|
25 |
+
*/
|
26 |
+
public function __construct( Payment_Gateway $gateway ) {
|
27 |
+
|
28 |
+
parent::__construct( $gateway );
|
29 |
+
|
30 |
+
// add hooks
|
31 |
+
$this->add_support();
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Adds support for pre-orders by hooking in some necessary actions
|
37 |
+
*
|
38 |
+
* @since 3.0.0
|
39 |
+
*/
|
40 |
+
public function add_support() {
|
41 |
+
|
42 |
+
$this->get_gateway()->add_support( array( 'pre-orders' ) );
|
43 |
+
|
44 |
+
// force tokenization when needed
|
45 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_tokenization_forced', array( $this, 'maybe_force_tokenization' ) );
|
46 |
+
|
47 |
+
// add pre-orders data to the order object
|
48 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_get_order', array( $this, 'get_order' ) );
|
49 |
+
|
50 |
+
// process pre-order initial payment as needed
|
51 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_process_payment', array( $this, 'process_payment' ), 10, 2 );
|
52 |
+
|
53 |
+
// complete a successful pre-order initial payment
|
54 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_complete_payment', array( $this, 'complete_payment' ), 10, 2 );
|
55 |
+
|
56 |
+
// process batch pre-order payments
|
57 |
+
add_action( 'wc_pre_orders_process_pre_order_completion_payment_' . $this->get_gateway()->get_id(), array( $this, 'process_release_payment' ) );
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Force tokenization for pre-orders
|
63 |
+
*
|
64 |
+
* @since 3.0.0
|
65 |
+
* @see Payment_Gateway::tokenization_forced()
|
66 |
+
* @param boolean $force_tokenization whether tokenization should be forced
|
67 |
+
* @return boolean true if tokenization should be forced, false otherwise
|
68 |
+
*/
|
69 |
+
public function maybe_force_tokenization( $force_tokenization ) {
|
70 |
+
|
71 |
+
// pay page with pre-order?
|
72 |
+
$pay_page_pre_order = false;
|
73 |
+
if ( $this->get_gateway()->is_pay_page_gateway() ) {
|
74 |
+
|
75 |
+
$order_id = $this->get_gateway()->get_checkout_pay_page_order_id();
|
76 |
+
|
77 |
+
if ( $order_id ) {
|
78 |
+
$pay_page_pre_order = \WC_Pre_Orders_Order::order_contains_pre_order( $order_id ) && \WC_Pre_Orders_Product::product_is_charged_upon_release( \WC_Pre_Orders_Order::get_pre_order_product( $order_id ) );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
if ( ( \WC_Pre_Orders_Cart::cart_contains_pre_order() && \WC_Pre_Orders_Product::product_is_charged_upon_release( \WC_Pre_Orders_Cart::get_pre_order_product() ) ) ||
|
83 |
+
$pay_page_pre_order ) {
|
84 |
+
|
85 |
+
// always tokenize the card for pre-orders that are charged upon release
|
86 |
+
$force_tokenization = true;
|
87 |
+
}
|
88 |
+
|
89 |
+
return $force_tokenization;
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Adds pre-orders data to the order object.
|
95 |
+
*
|
96 |
+
* Filtered onto Payment_Gateway::get_order()
|
97 |
+
*
|
98 |
+
* @see Payment_Gateway::get_order()
|
99 |
+
*
|
100 |
+
* @since 3.0.0
|
101 |
+
*
|
102 |
+
* @param \WC_Order $order the order
|
103 |
+
* @return \WC_Order
|
104 |
+
*/
|
105 |
+
public function get_order( $order ) {
|
106 |
+
|
107 |
+
// bail if order doesn't contain a pre-order
|
108 |
+
if ( ! \WC_Pre_Orders_Order::order_contains_pre_order( $order ) ) {
|
109 |
+
return $order;
|
110 |
+
}
|
111 |
+
|
112 |
+
if ( \WC_Pre_Orders_Order::order_requires_payment_tokenization( $order ) ) {
|
113 |
+
|
114 |
+
// normally a guest user wouldn't be assigned a customer id, but for a pre-order requiring tokenization, it might be
|
115 |
+
if ( 0 == $order->get_user_id() && false !== ( $customer_id = $this->get_gateway()->get_guest_customer_id( $order ) ) ) {
|
116 |
+
$order->customer_id = $customer_id;
|
117 |
+
}
|
118 |
+
|
119 |
+
// zero out the payment total since we're just tokenizing the payment method
|
120 |
+
$order->payment_total = '0.00';
|
121 |
+
|
122 |
+
} elseif ( \WC_Pre_Orders_Order::order_has_payment_token( $order ) && ! is_checkout_pay_page() ) {
|
123 |
+
|
124 |
+
// if this is a pre-order release payment with a tokenized payment method, get the payment token to complete the order
|
125 |
+
|
126 |
+
// retrieve the payment token
|
127 |
+
$order->payment->token = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'payment_token' );
|
128 |
+
|
129 |
+
// retrieve the optional customer id
|
130 |
+
$order->customer_id = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'customer_id' );
|
131 |
+
|
132 |
+
// set token data on order
|
133 |
+
if ( $this->get_gateway()->get_payment_tokens_handler()->user_has_token( $order->get_user_id(), $order->payment->token ) ) {
|
134 |
+
|
135 |
+
// an existing registered user with a saved payment token
|
136 |
+
$token = $this->get_gateway()->get_payment_tokens_handler()->get_token( $order->get_user_id(), $order->payment->token );
|
137 |
+
|
138 |
+
// account last four
|
139 |
+
$order->payment->account_number = $token->get_last_four();
|
140 |
+
|
141 |
+
if ( $this->get_gateway()->is_credit_card_gateway() ) {
|
142 |
+
|
143 |
+
// card type
|
144 |
+
$order->payment->card_type = $token->get_card_type();
|
145 |
+
|
146 |
+
// exp month/year
|
147 |
+
$order->payment->exp_month = $token->get_exp_month();
|
148 |
+
$order->payment->exp_year = $token->get_exp_year();
|
149 |
+
|
150 |
+
}
|
151 |
+
|
152 |
+
} else {
|
153 |
+
|
154 |
+
// a guest user means that token data must be set from the original order
|
155 |
+
|
156 |
+
// account number
|
157 |
+
$order->payment->account_number = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'account_four' );
|
158 |
+
|
159 |
+
if ( $this->get_gateway()->is_credit_card_gateway() ) {
|
160 |
+
|
161 |
+
// card type
|
162 |
+
$order->payment->card_type = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'card_type' );
|
163 |
+
|
164 |
+
// expiry date
|
165 |
+
if ( $expiry_date = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'card_expiry_date' ) ) {
|
166 |
+
list( $exp_year, $exp_month ) = explode( '-', $expiry_date );
|
167 |
+
$order->payment->exp_month = $exp_month;
|
168 |
+
$order->payment->exp_year = $exp_year;
|
169 |
+
}
|
170 |
+
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
return $order;
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Handle the pre-order initial payment/tokenization, or defer back to the normal payment
|
181 |
+
* processing flow
|
182 |
+
*
|
183 |
+
* @since 3.0.0
|
184 |
+
* @see Payment_Gateway::process_payment()
|
185 |
+
* @param boolean $result the result of this pre-order payment process
|
186 |
+
* @param int $order_id the order identifier
|
187 |
+
* @return true|array true to process this payment as a regular transaction, otherwise
|
188 |
+
* return an array containing keys 'result' and 'redirect'
|
189 |
+
*/
|
190 |
+
public function process_payment( $result, $order_id ) {
|
191 |
+
|
192 |
+
// processing pre-order
|
193 |
+
if ( \WC_Pre_Orders_Order::order_contains_pre_order( $order_id ) &&
|
194 |
+
\WC_Pre_Orders_Order::order_requires_payment_tokenization( $order_id ) ) {
|
195 |
+
|
196 |
+
$order = $this->get_gateway()->get_order( $order_id );
|
197 |
+
|
198 |
+
try {
|
199 |
+
|
200 |
+
// using an existing tokenized payment method
|
201 |
+
if ( isset( $order->payment->token ) && $order->payment->token ) {
|
202 |
+
|
203 |
+
// save the tokenized card info for completing the pre-order in the future
|
204 |
+
$this->get_gateway()->add_transaction_data( $order );
|
205 |
+
|
206 |
+
} else {
|
207 |
+
|
208 |
+
// otherwise tokenize the payment method
|
209 |
+
$order = $this->get_gateway()->get_payment_tokens_handler()->create_token( $order );
|
210 |
+
}
|
211 |
+
|
212 |
+
// mark order as pre-ordered / reduce order stock
|
213 |
+
\WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
214 |
+
|
215 |
+
// empty cart
|
216 |
+
WC()->cart->empty_cart();
|
217 |
+
|
218 |
+
// redirect to thank you page
|
219 |
+
$result = array(
|
220 |
+
'result' => 'success',
|
221 |
+
'redirect' => $this->get_gateway()->get_return_url( $order ),
|
222 |
+
);
|
223 |
+
|
224 |
+
} catch( \Exception $e ) {
|
225 |
+
|
226 |
+
$this->get_gateway()->mark_order_as_failed( $order, sprintf( esc_html__( 'Pre-Order Tokenization attempt failed (%s)', 'woocommerce-square' ), $this->get_gateway()->get_method_title(), $e->getMessage() ) );
|
227 |
+
|
228 |
+
$result = array(
|
229 |
+
'result' => 'failure',
|
230 |
+
'message' => $e->getMessage(),
|
231 |
+
);
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
+
return $result;
|
236 |
+
}
|
237 |
+
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Completes a pre-order payment by marking the order as Pre-Ordered.
|
241 |
+
*
|
242 |
+
* @internal
|
243 |
+
*
|
244 |
+
* @since 3.0.0
|
245 |
+
*
|
246 |
+
* @param \WC_Order $order order object
|
247 |
+
*/
|
248 |
+
public function complete_payment( $order ) {
|
249 |
+
|
250 |
+
if ( \WC_Pre_Orders_Order::order_contains_pre_order( $order ) && \WC_Pre_Orders_Order::order_requires_payment_tokenization( $order ) ) {
|
251 |
+
\WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order );
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Processes a pre-order payment when the pre-order is released.
|
258 |
+
*
|
259 |
+
* @since 3.0.0
|
260 |
+
*
|
261 |
+
* @param \WC_Order $order original order containing the pre-order
|
262 |
+
* @throws \Exception
|
263 |
+
*/
|
264 |
+
public function process_release_payment( $order ) {
|
265 |
+
|
266 |
+
try {
|
267 |
+
|
268 |
+
// set order defaults
|
269 |
+
$order = $this->get_gateway()->get_order( Order_Compatibility::get_prop( $order, 'id' ) );
|
270 |
+
|
271 |
+
// order description
|
272 |
+
$order->description = sprintf( esc_html__( '%s - Pre-Order Release Payment for Order %s', 'woocommerce-square' ), Square_Helper::get_site_name(), $order->get_order_number() );
|
273 |
+
|
274 |
+
// token is required
|
275 |
+
if ( ! $order->payment->token ) {
|
276 |
+
throw new \Exception( esc_html__( 'Payment token missing/invalid.', 'woocommerce-square' ) );
|
277 |
+
}
|
278 |
+
|
279 |
+
// perform the transaction
|
280 |
+
if ( $this->get_gateway()->is_credit_card_gateway() ) {
|
281 |
+
|
282 |
+
if ( $this->get_gateway()->perform_credit_card_charge( $order ) ) {
|
283 |
+
$response = $this->get_gateway()->get_api()->credit_card_charge( $order );
|
284 |
+
} else {
|
285 |
+
$response = $this->get_gateway()->get_api()->credit_card_authorization( $order );
|
286 |
+
}
|
287 |
+
|
288 |
+
}
|
289 |
+
|
290 |
+
// success! update order record
|
291 |
+
if ( $response->transaction_approved() ) {
|
292 |
+
|
293 |
+
$last_four = substr( $order->payment->account_number, -4 );
|
294 |
+
|
295 |
+
// order note based on gateway type
|
296 |
+
if ( $this->get_gateway()->is_credit_card_gateway() ) {
|
297 |
+
|
298 |
+
$message = sprintf(
|
299 |
+
esc_html__( '%s %s Pre-Order Release Payment Approved: %s ending in %s (expires %s)', 'woocommerce-square' ),
|
300 |
+
$this->get_gateway()->get_method_title(),
|
301 |
+
$this->get_gateway()->perform_credit_card_authorization( $order ) ? 'Authorization' : 'Charge',
|
302 |
+
Payment_Gateway_Helper::payment_type_to_name( ( ! empty( $order->payment->card_type ) ? $order->payment->card_type : 'card' ) ),
|
303 |
+
$last_four,
|
304 |
+
( ! empty( $order->payment->exp_month) && ! empty( $order->payment->exp_year ) ? $order->payment->exp_month . '/' . substr( $order->payment->exp_year, -2 ) : 'n/a' )
|
305 |
+
);
|
306 |
+
|
307 |
+
}
|
308 |
+
|
309 |
+
// adds the transaction id (if any) to the order note
|
310 |
+
if ( $response->get_transaction_id() ) {
|
311 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
312 |
+
}
|
313 |
+
|
314 |
+
$order->add_order_note( $message );
|
315 |
+
}
|
316 |
+
|
317 |
+
if ( $response->transaction_approved() || $response->transaction_held() ) {
|
318 |
+
|
319 |
+
// add the standard transaction data
|
320 |
+
$this->get_gateway()->add_transaction_data( $order, $response );
|
321 |
+
|
322 |
+
// allow the concrete class to add any gateway-specific transaction data to the order
|
323 |
+
$this->get_gateway()->add_payment_gateway_transaction_data( $order, $response );
|
324 |
+
|
325 |
+
// if the transaction was held (ie fraud validation failure) mark it as such
|
326 |
+
if ( $response->transaction_held() || ( $this->get_gateway()->supports( Payment_Gateway::FEATURE_CREDIT_CARD_AUTHORIZATION ) && $this->get_gateway()->perform_credit_card_authorization( $order ) ) ) {
|
327 |
+
|
328 |
+
$this->get_gateway()->mark_order_as_held( $order, $this->get_gateway()->supports( Payment_Gateway::FEATURE_CREDIT_CARD_AUTHORIZATION ) && $this->get_gateway()->perform_credit_card_authorization( $order ) ? esc_html__( 'Authorization only transaction', 'woocommerce-square' ) : $response->get_status_message(), $response );
|
329 |
+
|
330 |
+
wc_reduce_stock_levels( $order->get_id() ); // reduce stock for held orders, but don't complete payment
|
331 |
+
|
332 |
+
} else {
|
333 |
+
// otherwise complete the order
|
334 |
+
$order->payment_complete();
|
335 |
+
}
|
336 |
+
|
337 |
+
} else {
|
338 |
+
|
339 |
+
// failure
|
340 |
+
throw new \Exception( sprintf( '%s: %s', $response->get_status_code(), $response->get_status_message() ) );
|
341 |
+
|
342 |
+
}
|
343 |
+
|
344 |
+
} catch ( \Exception $e ) {
|
345 |
+
|
346 |
+
// Mark order as failed
|
347 |
+
$this->get_gateway()->mark_order_as_failed( $order, sprintf( esc_html__( 'Pre-Order Release Payment Failed: %s', 'woocommerce-square' ), $e->getMessage() ) );
|
348 |
+
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration_Subscriptions.php
ADDED
@@ -0,0 +1,673 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\Integrations;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
5 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Token;
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) or exit;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Subscriptions Integration
|
13 |
+
*
|
14 |
+
* @since 3.0.0
|
15 |
+
*/
|
16 |
+
class Payment_Gateway_Integration_Subscriptions extends Payment_Gateway_Integration {
|
17 |
+
|
18 |
+
|
19 |
+
/** @var string|float renewal payment total for Subs 2.0.x renewals */
|
20 |
+
protected $renewal_payment_total;
|
21 |
+
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Bootstraps the class.
|
25 |
+
*
|
26 |
+
* @since 3.0.0
|
27 |
+
*
|
28 |
+
* @param Payment_Gateway|Payment_Gateway_Direct $gateway
|
29 |
+
*/
|
30 |
+
public function __construct( Payment_Gateway $gateway ) {
|
31 |
+
|
32 |
+
parent::__construct( $gateway );
|
33 |
+
|
34 |
+
// add hooks
|
35 |
+
$this->add_support();
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Adds support for subscriptions by hooking in some necessary actions
|
41 |
+
*
|
42 |
+
* @since 3.0.0
|
43 |
+
*/
|
44 |
+
public function add_support() {
|
45 |
+
|
46 |
+
$this->get_gateway()->add_support( array(
|
47 |
+
'subscriptions',
|
48 |
+
'subscription_suspension',
|
49 |
+
'subscription_cancellation',
|
50 |
+
'subscription_reactivation',
|
51 |
+
'subscription_amount_changes',
|
52 |
+
'subscription_date_changes',
|
53 |
+
'multiple_subscriptions',
|
54 |
+
'subscription_payment_method_change_customer',
|
55 |
+
'subscription_payment_method_change_admin',
|
56 |
+
) );
|
57 |
+
|
58 |
+
// force tokenization when needed
|
59 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_tokenization_forced', array( $this, 'maybe_force_tokenization' ) );
|
60 |
+
|
61 |
+
// save token/customer ID to subscription objects
|
62 |
+
add_action( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_add_transaction_data', array( $this, 'save_payment_meta' ), 10, 2 );
|
63 |
+
|
64 |
+
// process renewal payments
|
65 |
+
add_action( 'woocommerce_scheduled_subscription_payment_' . $this->get_gateway()->get_id(), array( $this, 'process_renewal_payment' ), 10, 2 );
|
66 |
+
|
67 |
+
// update the customer/token ID on the subscription when updating a previously failing payment method
|
68 |
+
add_action( 'woocommerce_subscription_failing_payment_method_updated_' . $this->get_gateway()->get_id(), array( $this, 'update_failing_payment_method' ), 10, 2 );
|
69 |
+
|
70 |
+
// display the current payment method used for a subscription in the "My Subscriptions" table
|
71 |
+
add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'maybe_render_payment_method' ), 10, 3 );
|
72 |
+
|
73 |
+
// don't copy over order-specific meta to the WC_Subscription object during renewal processing
|
74 |
+
add_filter( 'wcs_renewal_order_meta', array( $this, 'do_not_copy_order_meta' ) );
|
75 |
+
|
76 |
+
// process the Change Payment "transaction"
|
77 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_process_payment', array( $this, 'process_change_payment' ), 10, 3 );
|
78 |
+
|
79 |
+
// remove order-specific meta from the Subscription object after the change payment method action
|
80 |
+
add_filter( 'woocommerce_subscriptions_process_payment_for_change_method_via_pay_shortcode', array( $this, 'remove_order_meta_from_change_payment' ), 10, 2 );
|
81 |
+
|
82 |
+
// don't copy over order-specific meta to the new WC_Subscription object during upgrade to 2.0.x
|
83 |
+
add_filter( 'wcs_upgrade_subscription_meta_to_copy', array( $this, 'do_not_copy_order_meta_during_upgrade' ) );
|
84 |
+
|
85 |
+
// allow concrete gateways to define additional order-specific meta keys to exclude
|
86 |
+
if ( is_callable( array( $this->get_gateway(), 'subscriptions_get_excluded_order_meta_keys' ) ) ) {
|
87 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_subscriptions_order_specific_meta_keys', array( $this->get_gateway(), 'subscriptions_get_excluded_order_meta_keys' ) );
|
88 |
+
}
|
89 |
+
|
90 |
+
/* My Payment Methods */
|
91 |
+
|
92 |
+
add_filter( 'wc_' . $this->get_gateway()->get_plugin()->get_id() . '_my_payment_methods_table_headers', array( $this, 'add_my_payment_methods_table_header' ), 10, 2 );
|
93 |
+
add_filter( 'wc_' . $this->get_gateway()->get_plugin()->get_id() . '_my_payment_methods_table_body_row_data', array( $this, 'add_my_payment_methods_table_body_row_data' ), 10, 3 );
|
94 |
+
add_filter( 'wc_' . $this->get_gateway()->get_plugin()->get_id() . '_my_payment_methods_table_method_actions', array( $this, 'disable_my_payment_methods_table_method_delete' ), 10, 3 );
|
95 |
+
|
96 |
+
/* Admin Change Payment Method support */
|
97 |
+
|
98 |
+
// framework defaults - payment_token and customer_id
|
99 |
+
add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'admin_add_payment_meta' ), 9, 2 );
|
100 |
+
add_action( 'woocommerce_subscription_validate_payment_meta_' . $this->get_gateway()->get_id(), array( $this, 'admin_validate_payment_meta' ), 9 );
|
101 |
+
|
102 |
+
// allow concrete gateways to add/change defaults
|
103 |
+
if ( is_callable( array( $this->get_gateway(), 'subscriptions_admin_add_payment_meta' ) ) ) {
|
104 |
+
add_filter( 'woocommerce_subscription_payment_meta', array( $this->get_gateway(), 'subscriptions_admin_add_payment_meta' ), 10, 2 );
|
105 |
+
}
|
106 |
+
|
107 |
+
// allow concrete gateways to perform additional validation
|
108 |
+
if ( is_callable( array( $this->get_gateway(), 'subscriptions_admin_validate_payment_meta' ) ) ) {
|
109 |
+
add_action( 'woocommerce_subscription_validate_payment_meta_' . $this->get_gateway()->get_id(), array( $this->get_gateway(), 'subscriptions_admin_validate_payment_meta' ), 10 );
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Force tokenization for subscriptions, this can be forced either during checkout
|
115 |
+
* or when the payment method for a subscription is being changed
|
116 |
+
*
|
117 |
+
* @since 3.0.0
|
118 |
+
* @see Payment_Gateway::tokenization_forced()
|
119 |
+
* @param bool $force_tokenization whether tokenization should be forced
|
120 |
+
* @return bool true if tokenization should be forced, false otherwise
|
121 |
+
*/
|
122 |
+
public function maybe_force_tokenization( $force_tokenization ) {
|
123 |
+
|
124 |
+
// pay page with subscription?
|
125 |
+
$pay_page_subscription = false;
|
126 |
+
if ( $this->get_gateway()->is_pay_page_gateway() ) {
|
127 |
+
|
128 |
+
$order_id = $this->get_gateway()->get_checkout_pay_page_order_id();
|
129 |
+
|
130 |
+
if ( $order_id ) {
|
131 |
+
$pay_page_subscription = wcs_order_contains_subscription( $order_id );
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
if ( \WC_Subscriptions_Cart::cart_contains_subscription() ||
|
136 |
+
wcs_cart_contains_renewal() ||
|
137 |
+
\WC_Subscriptions_Change_Payment_Gateway::$is_request_to_change_payment ||
|
138 |
+
$pay_page_subscription ) {
|
139 |
+
$force_tokenization = true;
|
140 |
+
}
|
141 |
+
|
142 |
+
return $force_tokenization;
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Save payment meta to the Subscription object after a successful transaction,
|
148 |
+
* this is primarily used for the payment token and customer ID which are then
|
149 |
+
* copied over to a renewal order prior to payment processing.
|
150 |
+
*
|
151 |
+
* @since 3.0.0
|
152 |
+
* @param \WC_Order $order order
|
153 |
+
*/
|
154 |
+
public function save_payment_meta( $order ) {
|
155 |
+
|
156 |
+
// a single order can contain multiple subscriptions
|
157 |
+
$subscriptions = wcs_get_subscriptions_for_order( Order_Compatibility::get_prop( $order, 'id' ), array(
|
158 |
+
'order_type' => array( 'any' ),
|
159 |
+
) );
|
160 |
+
|
161 |
+
foreach ( $subscriptions as $subscription ) {
|
162 |
+
|
163 |
+
// payment token
|
164 |
+
if ( ! empty( $order->payment->token ) ) {
|
165 |
+
update_post_meta( Order_Compatibility::get_prop( $subscription, 'id' ), $this->get_gateway()->get_order_meta_prefix() . 'payment_token', $order->payment->token );
|
166 |
+
}
|
167 |
+
|
168 |
+
// customer ID
|
169 |
+
if ( ! empty( $order->customer_id ) ) {
|
170 |
+
update_post_meta( Order_Compatibility::get_prop( $subscription, 'id' ), $this->get_gateway()->get_order_meta_prefix() . 'customer_id', $order->customer_id );
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Process a subscription renewal payment
|
178 |
+
*
|
179 |
+
* @since 3.0.0
|
180 |
+
* @param float $amount_to_charge subscription amount to charge, could include multiple renewals if they've previously failed and the admin has enabled it
|
181 |
+
* @param \WC_Order $order original order containing the subscription
|
182 |
+
*/
|
183 |
+
public function process_renewal_payment( $amount_to_charge, $order ) {
|
184 |
+
|
185 |
+
// set payment total so it can override the default in get_order()
|
186 |
+
$this->renewal_payment_total = Square_Helper::number_format( $amount_to_charge );
|
187 |
+
|
188 |
+
$token = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'payment_token' );
|
189 |
+
|
190 |
+
// payment token must be present and valid
|
191 |
+
if ( empty( $token ) || ! $this->get_gateway()->get_payment_tokens_handler()->user_has_token( $order->get_user_id(), $token ) ) {
|
192 |
+
|
193 |
+
$this->get_gateway()->mark_order_as_failed( $order, esc_html__( 'Subscription Renewal: payment token is missing/invalid.', 'woocommerce-square' ) );
|
194 |
+
|
195 |
+
return;
|
196 |
+
}
|
197 |
+
|
198 |
+
// add subscriptions data to the order object prior to processing the payment
|
199 |
+
add_filter( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_get_order', array( $this, 'get_order' ) );
|
200 |
+
|
201 |
+
$this->get_gateway()->process_payment( Order_Compatibility::get_prop( $order, 'id' ) );
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Adds subscriptions data to the order object, currently:
|
207 |
+
*
|
208 |
+
* + renewal order specific description
|
209 |
+
* + renewal payment total
|
210 |
+
* + token and associated data (last four, type, etc)
|
211 |
+
*
|
212 |
+
* @since 3.0.0
|
213 |
+
* @see Payment_Gateway_Direct::get_order()
|
214 |
+
* @param \WC_Order $order renewal order
|
215 |
+
* @return \WC_Order renewal order with payment token data set
|
216 |
+
*/
|
217 |
+
public function get_order( $order ) {
|
218 |
+
|
219 |
+
$order->description = sprintf( esc_html__( '%1$s - Subscription Renewal Order %2$s', 'woocommerce-square' ), wp_specialchars_decode( Square_Helper::get_site_name(), ENT_QUOTES ), $order->get_order_number() );
|
220 |
+
|
221 |
+
// override the payment total with the amount to charge given by Subscriptions
|
222 |
+
$order->payment_total = $this->renewal_payment_total;
|
223 |
+
|
224 |
+
// set payment token
|
225 |
+
$order->payment->token = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'payment_token' );
|
226 |
+
|
227 |
+
// use customer ID from renewal order, not user meta so the admin can update the customer ID for a subscription if needed
|
228 |
+
$customer_id = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'customer_id' );
|
229 |
+
|
230 |
+
// only if a customer ID exists in order meta, otherwise this will default to the previously set value from user meta
|
231 |
+
if ( ! empty( $customer_id ) ) {
|
232 |
+
$order->customer_id = $customer_id;
|
233 |
+
}
|
234 |
+
|
235 |
+
// get the token object
|
236 |
+
$token = $this->get_gateway()->get_payment_tokens_handler()->get_token( $order->get_user_id(), $order->payment->token );
|
237 |
+
|
238 |
+
// set token data on the order
|
239 |
+
$order->payment->account_number = $token->get_last_four();
|
240 |
+
$order->payment->last_four = $token->get_last_four();
|
241 |
+
|
242 |
+
if ( $token->is_credit_card() ) {
|
243 |
+
|
244 |
+
$order->payment->card_type = $token->get_card_type();
|
245 |
+
$order->payment->exp_month = $token->get_exp_month();
|
246 |
+
$order->payment->exp_year = $token->get_exp_year();
|
247 |
+
|
248 |
+
}
|
249 |
+
|
250 |
+
return $order;
|
251 |
+
}
|
252 |
+
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Don't copy order-specific meta to renewal orders from the WC_Subscription
|
256 |
+
* object. Generally the subscription object should not have any order-specific
|
257 |
+
* meta (aside from `payment_token` and `customer_id`) as they are not
|
258 |
+
* copied during the upgrade (see do_not_copy_order_meta_during_upgrade()), so
|
259 |
+
* this method is more of a fallback in case meta accidentally is copied.
|
260 |
+
*
|
261 |
+
* @since 3.0.0
|
262 |
+
* @param array $order_meta order meta to copy
|
263 |
+
* @return array
|
264 |
+
*/
|
265 |
+
public function do_not_copy_order_meta( $order_meta ) {
|
266 |
+
|
267 |
+
$meta_keys = $this->get_order_specific_meta_keys();
|
268 |
+
|
269 |
+
foreach ( $order_meta as $index => $meta ) {
|
270 |
+
|
271 |
+
if ( in_array( $meta['meta_key'], $meta_keys, true ) ) {
|
272 |
+
unset( $order_meta[ $index ] );
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
return $order_meta;
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Don't copy order-specific meta to the new WC_Subscription object during
|
282 |
+
* upgrade to 2.0.x. This only allows the `payment_token` and `customer_id`
|
283 |
+
* meta to be copied.
|
284 |
+
*
|
285 |
+
* @since 3.0.0
|
286 |
+
* @param array $order_meta order meta to copy
|
287 |
+
* @return array
|
288 |
+
*/
|
289 |
+
public function do_not_copy_order_meta_during_upgrade( $order_meta ) {
|
290 |
+
|
291 |
+
foreach ( $this->get_order_specific_meta_keys() as $meta_key ) {
|
292 |
+
|
293 |
+
if ( isset( $order_meta[ $meta_key ] ) ) {
|
294 |
+
unset( $order_meta[ $meta_key ] );
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
return $order_meta;
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Processes a Change Payment transaction.
|
304 |
+
*
|
305 |
+
* This hooks in before standard payment processing to simply add or create
|
306 |
+
* token data and avoid certain failure conditions affecting the subscription
|
307 |
+
* object.
|
308 |
+
*
|
309 |
+
* @internal
|
310 |
+
*
|
311 |
+
* @since 3.0.0
|
312 |
+
*
|
313 |
+
* @param bool|array $result result from any others filtering this
|
314 |
+
* @param int $order_id an order or subscription ID
|
315 |
+
* @param Payment_Gateway_Direct $gateway gateway object
|
316 |
+
* @return array $result change payment result
|
317 |
+
*/
|
318 |
+
public function process_change_payment( $result, $order_id, $gateway ) {
|
319 |
+
|
320 |
+
// if this is not a subscription and not changing payment, bail for normal order processing
|
321 |
+
if ( ! wcs_is_subscription( $order_id ) || ! did_action( 'woocommerce_subscription_change_payment_method_via_pay_shortcode' ) ) {
|
322 |
+
return $result;
|
323 |
+
}
|
324 |
+
|
325 |
+
$subscription = $gateway->get_order( $order_id );
|
326 |
+
|
327 |
+
try {
|
328 |
+
|
329 |
+
// if using a saved method, just add the data
|
330 |
+
if ( isset( $subscription->payment->token ) && $subscription->payment->token ) {
|
331 |
+
|
332 |
+
$gateway->add_transaction_data( $subscription );
|
333 |
+
|
334 |
+
// otherwise...tokenize
|
335 |
+
} else {
|
336 |
+
|
337 |
+
$subscription = $gateway->get_payment_tokens_handler()->create_token( $subscription );
|
338 |
+
}
|
339 |
+
|
340 |
+
$result = array(
|
341 |
+
'result' => 'success',
|
342 |
+
'redirect' => $subscription->get_view_order_url(),
|
343 |
+
);
|
344 |
+
|
345 |
+
} catch ( \Exception $e ) {
|
346 |
+
|
347 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - error message; e.g. Order Note: [Payment method] Payment Change failed [error] */
|
348 |
+
$note = sprintf( esc_html__( '%1$s Payment Change Failed (%2$s)', 'woocommerce-square' ), $gateway->get_method_title(), $e->getMessage() );
|
349 |
+
|
350 |
+
// add a subscription note to keep track of failures
|
351 |
+
$subscription->add_order_note( $note );
|
352 |
+
|
353 |
+
Square_Helper::wc_add_notice( esc_html__( 'An error occurred, please try again or try an alternate form of payment.', 'woocommerce-square' ), 'error' );
|
354 |
+
|
355 |
+
// this isn't used by Subscriptions, but return a failure result anyway
|
356 |
+
$result = array(
|
357 |
+
'result' => 'failure',
|
358 |
+
'message' => $e->getMessage(),
|
359 |
+
);
|
360 |
+
}
|
361 |
+
|
362 |
+
return $result;
|
363 |
+
}
|
364 |
+
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Remove order meta (like trans ID) that's added to a Subscription object
|
368 |
+
* during the change payment method flow, which uses WC_Payment_Gateway::process_payment(),
|
369 |
+
* thus some order-specific meta is added that is undesirable to have copied
|
370 |
+
* over to renewal orders.
|
371 |
+
*
|
372 |
+
* @since 3.0.0
|
373 |
+
* @param array $result process_payment() result, unused
|
374 |
+
* @param \WC_Subscription $subscription subscription object
|
375 |
+
* @return array
|
376 |
+
*/
|
377 |
+
public function remove_order_meta_from_change_payment( $result, $subscription ) {
|
378 |
+
|
379 |
+
// remove order-specific meta
|
380 |
+
foreach ( $this->get_order_specific_meta_keys() as $meta_key ) {
|
381 |
+
delete_post_meta( Order_Compatibility::get_prop( $subscription, 'id' ), $meta_key );
|
382 |
+
}
|
383 |
+
|
384 |
+
// get a fresh subscription object after previous metadata changes
|
385 |
+
$subscription = wcs_get_subscription( Order_Compatibility::get_prop( $subscription, 'id' ) );
|
386 |
+
|
387 |
+
$old_payment_method = Order_Compatibility::get_meta( $subscription, '_old_payment_method' );
|
388 |
+
$new_payment_method = Order_Compatibility::get_prop( $subscription, 'payment_method' );
|
389 |
+
|
390 |
+
// if the payment method has been changed to another gateway, additionally remove the old payment token and customer ID meta
|
391 |
+
if ( $new_payment_method !== $this->get_gateway()->get_id() && $old_payment_method === $this->get_gateway()->get_id() ) {
|
392 |
+
$this->get_gateway()->delete_order_meta( $subscription, 'payment_token' );
|
393 |
+
$this->get_gateway()->delete_order_meta( $subscription, 'customer_id' );
|
394 |
+
}
|
395 |
+
|
396 |
+
return $result;
|
397 |
+
}
|
398 |
+
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Update the payment token and optional customer ID for a subscription after a customer
|
402 |
+
* uses this gateway to successfully complete the payment for an automatic
|
403 |
+
* renewal payment which had previously failed.
|
404 |
+
*
|
405 |
+
* @since 3.0.0
|
406 |
+
* @param \WC_Subscription $subscription subscription being updated
|
407 |
+
* @param \WC_Order $renewal_order order which recorded the successful payment (to make up for the failed automatic payment).
|
408 |
+
*/
|
409 |
+
public function update_failing_payment_method( $subscription, $renewal_order ) {
|
410 |
+
|
411 |
+
// if the order doesn't have a transaction date stored, bail
|
412 |
+
// this prevents updating the subscription with a failing token in case the merchant is switching the order status manually without new payment
|
413 |
+
if ( ! $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $renewal_order, 'id' ), 'trans_date' ) ) {
|
414 |
+
return;
|
415 |
+
}
|
416 |
+
|
417 |
+
if ( $customer_id = $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $renewal_order, 'id' ), 'customer_id' ) ) {
|
418 |
+
$this->get_gateway()->update_order_meta( $subscription, 'customer_id', $customer_id );
|
419 |
+
}
|
420 |
+
|
421 |
+
$this->get_gateway()->update_order_meta( $subscription, 'payment_token', $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $renewal_order, 'id' ), 'payment_token' ) );
|
422 |
+
}
|
423 |
+
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Get the order-specific meta keys that should not be copied to the WC_Subscription
|
427 |
+
* object during upgrade to 2.0.x or during change payment method actions
|
428 |
+
*
|
429 |
+
* @since 3.0.0
|
430 |
+
* @return array
|
431 |
+
*/
|
432 |
+
protected function get_order_specific_meta_keys() {
|
433 |
+
|
434 |
+
$keys = array(
|
435 |
+
'trans_id',
|
436 |
+
'trans_date',
|
437 |
+
'account_four',
|
438 |
+
'card_expiry_date',
|
439 |
+
'card_type',
|
440 |
+
'authorization_code',
|
441 |
+
'auth_can_be_captured',
|
442 |
+
'charge_captured',
|
443 |
+
'capture_trans_id',
|
444 |
+
'account_type',
|
445 |
+
'check_number',
|
446 |
+
'environment',
|
447 |
+
'retry_count',
|
448 |
+
);
|
449 |
+
|
450 |
+
foreach ( $keys as $index => $key ) {
|
451 |
+
|
452 |
+
$keys[ $index ] = $this->get_gateway()->get_order_meta_prefix() . $key;
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Filter Subscriptions order-specific meta keys
|
457 |
+
*
|
458 |
+
* Use this to include additional meta keys that should not be copied over
|
459 |
+
* to the WC_Subscriptions object during renewal payments, the
|
460 |
+
* change payment method action, or the upgrade to 2.0.x.
|
461 |
+
*
|
462 |
+
* @since 3.0.0
|
463 |
+
* @param array $keys meta keys, with gateway order meta prefix included
|
464 |
+
* @param \Payment_Gateway_Integration_Subscriptions $this subscriptions integration class instance
|
465 |
+
*/
|
466 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_subscriptions_order_specific_meta_keys', $keys, $this );
|
467 |
+
}
|
468 |
+
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Render the payment method used for a subscription in the "My Subscriptions" table
|
472 |
+
*
|
473 |
+
* @since 3.0.0
|
474 |
+
* @param string $payment_method_to_display the default payment method text to display
|
475 |
+
* @param \WC_Subscription $subscription
|
476 |
+
* @return string the subscription payment method
|
477 |
+
*/
|
478 |
+
public function maybe_render_payment_method( $payment_method_to_display, $subscription ) {
|
479 |
+
|
480 |
+
// bail for other payment methods
|
481 |
+
if ( $this->get_gateway()->get_id() !== Order_Compatibility::get_prop( $subscription, 'payment_method' ) ) {
|
482 |
+
return $payment_method_to_display;
|
483 |
+
}
|
484 |
+
|
485 |
+
$token = $this->get_gateway()->get_payment_tokens_handler()->get_token( $subscription->get_user_id(), $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $subscription, 'id' ), 'payment_token' ) );
|
486 |
+
|
487 |
+
if ( $token instanceof Payment_Gateway_Payment_Token ) {
|
488 |
+
$payment_method_to_display = sprintf( esc_html__( 'Via %s ending in %s', 'woocommerce-square' ), $token->get_type_full(), $token->get_last_four() );
|
489 |
+
}
|
490 |
+
|
491 |
+
return $payment_method_to_display;
|
492 |
+
}
|
493 |
+
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Add a subscriptions header to the My Payment Methods table.
|
497 |
+
*
|
498 |
+
* @since 3.0.0
|
499 |
+
* @param array $headers the table headers
|
500 |
+
* @param \Payment_Gateway_My_Payment_Methods the my payment methods instance
|
501 |
+
* @return array
|
502 |
+
*/
|
503 |
+
public function add_my_payment_methods_table_header( $headers, $handler ) {
|
504 |
+
|
505 |
+
if ( isset( $headers['subscriptions'] ) ) {
|
506 |
+
return $headers;
|
507 |
+
}
|
508 |
+
|
509 |
+
$new_headers = array();
|
510 |
+
|
511 |
+
foreach ( $headers as $id => $label ) {
|
512 |
+
|
513 |
+
// Add the header before the actions
|
514 |
+
if ( 'actions' === $id ) {
|
515 |
+
$new_headers['subscriptions'] = esc_html__( 'Subscriptions', 'woocommerce-square' );
|
516 |
+
}
|
517 |
+
|
518 |
+
$new_headers[ $id ] = $label;
|
519 |
+
}
|
520 |
+
|
521 |
+
return $new_headers;
|
522 |
+
}
|
523 |
+
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Add a subscriptions header to the My Payment Methods table.
|
527 |
+
*
|
528 |
+
* @since 3.0.0
|
529 |
+
* @param array $method the table row data
|
530 |
+
* @param \Payment_Gateway_Payment_Token $token the payment token
|
531 |
+
* @param \Payment_Gateway_My_Payment_Methods the my payment methods instance
|
532 |
+
* @return array
|
533 |
+
*/
|
534 |
+
public function add_my_payment_methods_table_body_row_data( $method, $token, $handler ) {
|
535 |
+
|
536 |
+
// If the subscription data has already been added or this method is for a different gateway, bail
|
537 |
+
if ( isset( $method['subscriptions'] ) || str_replace( '_', '-', $token->get_type() ) !== $this->get_gateway()->get_payment_type() ) {
|
538 |
+
return $method;
|
539 |
+
}
|
540 |
+
|
541 |
+
$subscription_ids = array();
|
542 |
+
|
543 |
+
// Build a link for each subscription
|
544 |
+
foreach ( $this->get_payment_token_subscriptions( get_current_user_id(), $token ) as $subscription ) {
|
545 |
+
$subscription_ids[] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $subscription->get_view_order_url() ), esc_attr( sprintf( _x( '#%s', 'hash before order number', 'woocommerce-square' ), $subscription->get_order_number() ) ) );
|
546 |
+
}
|
547 |
+
|
548 |
+
if ( ! empty( $subscription_ids ) ) {
|
549 |
+
$method['subscriptions'] = implode( ', ', $subscription_ids );
|
550 |
+
}
|
551 |
+
|
552 |
+
return $method;
|
553 |
+
}
|
554 |
+
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Disables the "Delete" My Payment Methods method action button if there is an associated subscription.
|
558 |
+
*
|
559 |
+
* @since 3.0.0
|
560 |
+
*
|
561 |
+
* @param array $actions the token actions
|
562 |
+
* @param Payment_Gateway_Payment_Token the token object
|
563 |
+
* @param Payment_Gateway_My_Payment_Methods the my payment methods instance
|
564 |
+
* @return array
|
565 |
+
*/
|
566 |
+
public function disable_my_payment_methods_table_method_delete( $actions, $token, $handler ) {
|
567 |
+
|
568 |
+
$disable_delete = false;
|
569 |
+
|
570 |
+
$subscriptions = $this->get_payment_token_subscriptions( get_current_user_id(), $token );
|
571 |
+
|
572 |
+
// Check each subscription for the ability to change the payment method
|
573 |
+
foreach ( $subscriptions as $subscription ) {
|
574 |
+
|
575 |
+
if ( $subscription->can_be_updated_to( 'new-payment-method' ) ) {
|
576 |
+
$disable_delete = true;
|
577 |
+
break;
|
578 |
+
}
|
579 |
+
}
|
580 |
+
|
581 |
+
// if at least one can be changed, no deleting for you!
|
582 |
+
if ( isset( $actions['delete'] ) && $disable_delete ) {
|
583 |
+
$actions['delete']['class'] = array_merge( (array) $actions['delete']['class'], array( 'disabled' ) );
|
584 |
+
$actions['delete']['tip'] = esc_html__( 'This payment method is tied to a subscription and cannot be deleted. Please switch the subscription to another method first.', 'woocommerce-square' );
|
585 |
+
}
|
586 |
+
|
587 |
+
return $actions;
|
588 |
+
}
|
589 |
+
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Gets the subscriptions tied to a user payment token.
|
593 |
+
*
|
594 |
+
* @since 3.0.0
|
595 |
+
*
|
596 |
+
* @param int $user_id the user
|
597 |
+
* @param Payment_Gateway_Payment_Token the token object
|
598 |
+
* @return array the subscriptions or an empty array
|
599 |
+
*/
|
600 |
+
protected function get_payment_token_subscriptions( $user_id, $token ) {
|
601 |
+
|
602 |
+
$subscriptions = wcs_get_users_subscriptions( $user_id );
|
603 |
+
|
604 |
+
foreach ( $subscriptions as $key => $subscription ) {
|
605 |
+
|
606 |
+
$payment_method = Order_Compatibility::get_prop( $subscription, 'payment_method' );
|
607 |
+
$stored_token_id = (string) $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $subscription, 'id' ), 'payment_token' );
|
608 |
+
|
609 |
+
if ( $stored_token_id !== (string) $token->get_id() || $payment_method !== $this->get_gateway()->get_id() ) {
|
610 |
+
unset( $subscriptions[ $key ] );
|
611 |
+
}
|
612 |
+
}
|
613 |
+
|
614 |
+
return $subscriptions;
|
615 |
+
}
|
616 |
+
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Include the payment meta data required to process automatic recurring
|
620 |
+
* payments so that store managers can manually set up automatic recurring
|
621 |
+
* payments for a customer via the Edit Subscriptions screen in 2.0.x
|
622 |
+
*
|
623 |
+
* @since 3.0.0
|
624 |
+
* @param array $meta associative array of meta data required for automatic payments
|
625 |
+
* @param \WC_Subscription $subscription subscription object
|
626 |
+
* @return array
|
627 |
+
*/
|
628 |
+
public function admin_add_payment_meta( $meta, $subscription ) {
|
629 |
+
|
630 |
+
$prefix = $this->get_gateway()->get_order_meta_prefix();
|
631 |
+
|
632 |
+
$meta[ $this->get_gateway()->get_id() ] = array(
|
633 |
+
'post_meta' => array(
|
634 |
+
$prefix . 'payment_token' => array(
|
635 |
+
'value' => $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $subscription, 'id' ), 'payment_token' ),
|
636 |
+
'label' => esc_html__( 'Payment Token', 'woocommerce-square' ),
|
637 |
+
),
|
638 |
+
$prefix . 'customer_id' => array(
|
639 |
+
'value' => $this->get_gateway()->get_order_meta( Order_Compatibility::get_prop( $subscription, 'id' ), 'customer_id' ),
|
640 |
+
'label' => esc_html__( 'Customer ID', 'woocommerce-square' ),
|
641 |
+
),
|
642 |
+
)
|
643 |
+
);
|
644 |
+
|
645 |
+
return $meta;
|
646 |
+
}
|
647 |
+
|
648 |
+
|
649 |
+
/**
|
650 |
+
* Validate the payment meta data required to process automatic recurring
|
651 |
+
* payments so that store managers can manually set up automatic recurring
|
652 |
+
* payments for a customer via the Edit Subscriptions screen in 2.0.x
|
653 |
+
*
|
654 |
+
* @since 3.0.0
|
655 |
+
*
|
656 |
+
* @param array $meta associative array of meta data required for automatic payments
|
657 |
+
* @throws \Exception if payment token or customer ID is missing or blank
|
658 |
+
*/
|
659 |
+
public function admin_validate_payment_meta( $meta ) {
|
660 |
+
|
661 |
+
$prefix = $this->get_gateway()->get_order_meta_prefix();
|
662 |
+
|
663 |
+
// payment token
|
664 |
+
if ( empty( $meta['post_meta'][ $prefix . 'payment_token' ]['value'] ) ) {
|
665 |
+
throw new \Exception( sprintf( esc_html__( '%s is required.', 'woocommerce-square' ), $meta['post_meta'][ $prefix . 'payment_token' ]['label'] ) );
|
666 |
+
}
|
667 |
+
|
668 |
+
// customer ID - optional for some gateways so check if it's set first
|
669 |
+
if ( isset( $meta['post_meta'][ $prefix . 'customer_id'] ) && empty( $meta['post_meta'][ $prefix . 'customer_id' ]['value'] ) ) {
|
670 |
+
throw new \Exception( sprintf( esc_html__( '%s is required.', 'woocommerce-square' ), $meta['post_meta'][ $prefix . 'customer_id' ]['label'] ) );
|
671 |
+
}
|
672 |
+
}
|
673 |
+
}
|
includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Token.php
ADDED
@@ -0,0 +1,366 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\PaymentTokens;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
5 |
+
|
6 |
+
defined( 'ABSPATH' ) or exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* WooCommerce Payment Gateway Token
|
10 |
+
*
|
11 |
+
* Represents a credit card or check payment token
|
12 |
+
*/
|
13 |
+
class Payment_Gateway_Payment_Token {
|
14 |
+
|
15 |
+
|
16 |
+
/** @var string payment gateway token ID */
|
17 |
+
protected $id;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array associated token data
|
21 |
+
*/
|
22 |
+
protected $data;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var string payment type image url
|
26 |
+
*/
|
27 |
+
protected $img_url;
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Initialize a payment token with associated $data which is expected to
|
32 |
+
* have the following members:
|
33 |
+
*
|
34 |
+
* default - boolean optional indicates this is the default payment token
|
35 |
+
* type - string one of 'credit_card' or 'echeck' ('check' for backwards compatibility)
|
36 |
+
* last_four - string last four digits of account number
|
37 |
+
* card_type - string credit card type: visa, mc, amex, disc, diners, jcb, etc (credit card only)
|
38 |
+
* exp_month - string optional expiration month MM (credit card only)
|
39 |
+
* exp_year - string optional expiration year YYYY (credit card only)
|
40 |
+
* account_type - string one of 'checking' or 'savings' (checking gateway only)
|
41 |
+
*
|
42 |
+
* @since 3.0.0
|
43 |
+
* @param string $id the payment gateway token ID
|
44 |
+
* @param array $data associated data
|
45 |
+
*/
|
46 |
+
public function __construct( $id, $data ) {
|
47 |
+
|
48 |
+
if ( isset( $data['type'] ) && 'credit_card' == $data['type'] ) {
|
49 |
+
|
50 |
+
// normalize the provided card type to adjust for possible abbreviations if set
|
51 |
+
if ( isset( $data['card_type'] ) && $data['card_type'] ) {
|
52 |
+
|
53 |
+
$data['card_type'] = Payment_Gateway_Helper::normalize_card_type( $data['card_type'] );
|
54 |
+
|
55 |
+
// otherwise, get the payment type from the account number
|
56 |
+
} elseif ( isset( $data['account_number'] ) ) {
|
57 |
+
|
58 |
+
$data['card_type'] = Payment_Gateway_Helper::card_type_from_account_number( $data['account_number'] );
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// remove account number so it's not saved to the token
|
63 |
+
unset( $data['account_number'] );
|
64 |
+
|
65 |
+
$this->id = $id;
|
66 |
+
$this->data = $data;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Returns the payment token string
|
71 |
+
*
|
72 |
+
* @since 3.0.0
|
73 |
+
* @return string payment token string
|
74 |
+
*/
|
75 |
+
public function get_id() {
|
76 |
+
|
77 |
+
return $this->id;
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Returns true if this payment token is default
|
83 |
+
*
|
84 |
+
* @since 3.0.0
|
85 |
+
* @return boolean true if this payment token is default
|
86 |
+
*/
|
87 |
+
public function is_default() {
|
88 |
+
|
89 |
+
return isset( $this->data['default'] ) && $this->data['default'];
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Makes this payment token the default or a non-default one
|
95 |
+
*
|
96 |
+
* @since 3.0.0
|
97 |
+
* @param boolean $default true or false
|
98 |
+
*/
|
99 |
+
public function set_default( $default ) {
|
100 |
+
|
101 |
+
$this->data['default'] = $default;
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Returns true if this payment token represents a credit card
|
107 |
+
*
|
108 |
+
* @since 3.0.0
|
109 |
+
* @return boolean true if this payment token represents a credit card
|
110 |
+
*/
|
111 |
+
public function is_credit_card() {
|
112 |
+
|
113 |
+
return 'credit_card' == $this->data['type'];
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Returns the payment type, one of 'credit_card' or 'echeck'
|
118 |
+
*
|
119 |
+
* @since 3.0.0
|
120 |
+
* @return string the payment type
|
121 |
+
*/
|
122 |
+
public function get_type() {
|
123 |
+
|
124 |
+
return $this->data['type'];
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Returns the card type ie visa, mc, amex, disc, diners, jcb, etc
|
130 |
+
*
|
131 |
+
* Credit card gateway only
|
132 |
+
*
|
133 |
+
* @since 3.0.0
|
134 |
+
* @return string the payment type
|
135 |
+
*/
|
136 |
+
public function get_card_type() {
|
137 |
+
|
138 |
+
return isset( $this->data['card_type'] ) ? $this->data['card_type'] : null;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Returns the bank account type, one of 'checking' or 'savings'
|
143 |
+
*
|
144 |
+
* eCheck gateway only
|
145 |
+
*
|
146 |
+
* @since 3.0.0
|
147 |
+
* @return string the payment type
|
148 |
+
*/
|
149 |
+
public function get_account_type() {
|
150 |
+
|
151 |
+
return isset( $this->data['account_type'] ) ? $this->data['account_type'] : null;
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Set the account type
|
157 |
+
*
|
158 |
+
* eCheck gateway only
|
159 |
+
*
|
160 |
+
* @since 3.0.0
|
161 |
+
* @param string $account_type
|
162 |
+
*/
|
163 |
+
public function set_account_type( $account_type ) {
|
164 |
+
|
165 |
+
$this->data['account_type'] = $account_type;
|
166 |
+
}
|
167 |
+
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Returns the full payment type, ie Visa, MasterCard, American Express,
|
171 |
+
* Discover, Diners, JCB, eCheck, etc
|
172 |
+
*
|
173 |
+
* @since 3.0.0
|
174 |
+
* @return string the payment type
|
175 |
+
*/
|
176 |
+
public function get_type_full() {
|
177 |
+
|
178 |
+
if ( $this->is_credit_card() ) {
|
179 |
+
$type = $this->get_card_type() ? $this->get_card_type() : 'card';
|
180 |
+
} else {
|
181 |
+
$type = $this->get_account_type() ? $this->get_account_type() : 'bank';
|
182 |
+
}
|
183 |
+
|
184 |
+
return Payment_Gateway_Helper::payment_type_to_name( $type );
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Returns the last four digits of the credit card or check account number
|
190 |
+
*
|
191 |
+
* @since 3.0.0
|
192 |
+
* @return string last four of account
|
193 |
+
*/
|
194 |
+
public function get_last_four() {
|
195 |
+
|
196 |
+
return isset( $this->data['last_four'] ) ? $this->data['last_four'] : null;
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Set the account last four
|
202 |
+
*
|
203 |
+
* @since 3.0.0
|
204 |
+
* @param string $last_four
|
205 |
+
*/
|
206 |
+
public function set_last_four( $last_four ) {
|
207 |
+
|
208 |
+
$this->data['last_four'] = $last_four;
|
209 |
+
}
|
210 |
+
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Returns the expiration month of the credit card. This should only be
|
214 |
+
* called for credit card tokens
|
215 |
+
*
|
216 |
+
* @since 3.0.0
|
217 |
+
* @return string expiration month as a two-digit number
|
218 |
+
*/
|
219 |
+
public function get_exp_month() {
|
220 |
+
|
221 |
+
return isset( $this->data['exp_month'] ) ? $this->data['exp_month'] : null;
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Set the expiration month
|
227 |
+
*
|
228 |
+
* @since 3.0.0
|
229 |
+
* @param string $month
|
230 |
+
*/
|
231 |
+
public function set_exp_month( $month ) {
|
232 |
+
|
233 |
+
$this->data['exp_month'] = $month;
|
234 |
+
}
|
235 |
+
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Returns the expiration year of the credit card. This should only be
|
239 |
+
* called for credit card tokens
|
240 |
+
*
|
241 |
+
* @since 3.0.0
|
242 |
+
* @return string expiration year as a four-digit number
|
243 |
+
*/
|
244 |
+
public function get_exp_year() {
|
245 |
+
|
246 |
+
return isset( $this->data['exp_year'] ) ? $this->data['exp_year'] : null;
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Set the expiration year
|
252 |
+
*
|
253 |
+
* @since 3.0.0
|
254 |
+
* @param string $year
|
255 |
+
*/
|
256 |
+
public function set_exp_year( $year ) {
|
257 |
+
|
258 |
+
$this->data['exp_year'] = $year;
|
259 |
+
}
|
260 |
+
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Returns the expiration date in the format MM/YY, suitable for use
|
264 |
+
* in order notes or other customer-facing areas
|
265 |
+
*
|
266 |
+
* @since 3.0.0
|
267 |
+
* @return string formatted expiration date
|
268 |
+
*/
|
269 |
+
public function get_exp_date() {
|
270 |
+
|
271 |
+
return $this->get_exp_month() . '/' . substr( $this->get_exp_year(), -2 );
|
272 |
+
}
|
273 |
+
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Set the full image URL based on the token payment type. Note that this
|
277 |
+
* is available for convenience during a single request and will not be
|
278 |
+
* included in persistent storage
|
279 |
+
*
|
280 |
+
* @see Payment_Gateway_Payment_Token::get_image_url()
|
281 |
+
* @since 3.0.0
|
282 |
+
* @param string $url the full image URL
|
283 |
+
*/
|
284 |
+
public function set_image_url( $url ) {
|
285 |
+
|
286 |
+
$this->img_url = $url;
|
287 |
+
}
|
288 |
+
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Get the full image URL based on teh token payment type.
|
292 |
+
*
|
293 |
+
* @see Payment_Gateway_Payment_Token::set_image_url()
|
294 |
+
* @since 3.0.0
|
295 |
+
* @return string the full image URL
|
296 |
+
*/
|
297 |
+
public function get_image_url() {
|
298 |
+
|
299 |
+
return $this->img_url;
|
300 |
+
}
|
301 |
+
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Gets the payment method nickname.
|
305 |
+
*
|
306 |
+
* @since 3.0.0
|
307 |
+
*
|
308 |
+
* @return string
|
309 |
+
*/
|
310 |
+
public function get_nickname() {
|
311 |
+
|
312 |
+
return isset( $this->data['nickname'] ) ? $this->data['nickname'] : '';
|
313 |
+
}
|
314 |
+
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Sets the payment method nickname.
|
318 |
+
*
|
319 |
+
* @since 3.0.0
|
320 |
+
*
|
321 |
+
* @param string $value nickname value
|
322 |
+
*/
|
323 |
+
public function set_nickname( $value ) {
|
324 |
+
|
325 |
+
$this->data['nickname'] = $value;
|
326 |
+
}
|
327 |
+
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Gets the billing address hash.
|
331 |
+
*
|
332 |
+
* @since 3.0.0
|
333 |
+
*
|
334 |
+
* @return string
|
335 |
+
*/
|
336 |
+
public function get_billing_hash() {
|
337 |
+
|
338 |
+
return isset( $this->data['billing_hash'] ) ? $this->data['billing_hash'] : '';
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Sets the billing hash.
|
344 |
+
*
|
345 |
+
* @since 3.0.0
|
346 |
+
*
|
347 |
+
* @param string $value billing hash
|
348 |
+
*/
|
349 |
+
public function set_billing_hash( $value ) {
|
350 |
+
|
351 |
+
$this->data['billing_hash'] = $value;
|
352 |
+
}
|
353 |
+
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Returns a representation of this token suitable for persisting to a
|
357 |
+
* datastore
|
358 |
+
*
|
359 |
+
* @since 3.0.0
|
360 |
+
* @return mixed datastore representation of token
|
361 |
+
*/
|
362 |
+
public function to_datastore_format() {
|
363 |
+
|
364 |
+
return $this->data;
|
365 |
+
}
|
366 |
+
}
|
includes/Framework/PaymentGateway/PaymentTokens/Payment_Gateway_Payment_Tokens_Handler.php
ADDED
@@ -0,0 +1,859 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway\PaymentTokens;
|
4 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway;
|
5 |
+
use WooCommerce\Square\Framework\Addresses\Customer_Address;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Response;
|
8 |
+
use WooCommerce\Square\Framework\PaymentGateway\Admin\Payment_Gateway_Admin_Payment_Token_Editor;
|
9 |
+
|
10 |
+
defined( 'ABSPATH' ) or exit;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Handle the payment tokenization related functionality.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Payment_Gateway_Payment_Tokens_Handler {
|
18 |
+
|
19 |
+
/** @var string the gateway environment ID */
|
20 |
+
protected $environment_id;
|
21 |
+
|
22 |
+
/** @var array|Payment_Gateway_Payment_Token[] array of cached user id to array of Payment_Gateway_Payment_Token token objects */
|
23 |
+
protected $tokens;
|
24 |
+
|
25 |
+
/** @var Payment_Gateway gateway instance */
|
26 |
+
protected $gateway;
|
27 |
+
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Build the class.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
*
|
34 |
+
* @param Payment_Gateway $gateway payment gateway instance
|
35 |
+
*/
|
36 |
+
public function __construct( Payment_Gateway $gateway ) {
|
37 |
+
|
38 |
+
$this->gateway = $gateway;
|
39 |
+
|
40 |
+
$this->environment_id = $gateway->get_environment();
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* A factory method to build and return a payment token object for the
|
46 |
+
* gateway. Concrete classes can override this method to return a custom
|
47 |
+
* payment token implementation.
|
48 |
+
*
|
49 |
+
* @since 3.0.0
|
50 |
+
*
|
51 |
+
* @param string $token payment token
|
52 |
+
* @param array $data {
|
53 |
+
* Payment token data.
|
54 |
+
*
|
55 |
+
* @type bool $default Optional. Indicates this is the default payment token
|
56 |
+
* @type string $type Payment type. Either 'credit_card' or 'check'
|
57 |
+
* @type string $last_four Last four digits of account number
|
58 |
+
* @type string $card_type Credit card type (`visa`, `mc`, `amex`, `disc`, `diners`, `jcb`) or `echeck`
|
59 |
+
* @type string $exp_month Optional. Expiration month (credit card only)
|
60 |
+
* @type string $exp_year Optional. Expiration year (credit card only)
|
61 |
+
* }
|
62 |
+
* @return Payment_Gateway_Payment_Token payment token
|
63 |
+
*/
|
64 |
+
public function build_token( $token, $data ) {
|
65 |
+
|
66 |
+
return new Payment_Gateway_Payment_Token( $token, $data );
|
67 |
+
}
|
68 |
+
|
69 |
+
|
70 |
+
/** Handle single tokens **********************************************************************/
|
71 |
+
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Tokenizes the current payment method and adds the standard transaction
|
75 |
+
* data to the order post record.
|
76 |
+
*
|
77 |
+
* @since 3.0.0
|
78 |
+
*
|
79 |
+
* @param \WC_Order $order order object
|
80 |
+
* @param Payment_Gateway_API_Create_Payment_Token_Response|null $response payment token API response, or null if the request should be made
|
81 |
+
* @param string $environment_id optional environment ID, defaults to the current environment
|
82 |
+
* @return \WC_Order order object
|
83 |
+
* @throws \Exception on transaction failure
|
84 |
+
*/
|
85 |
+
public function create_token( \WC_Order $order, $response = null, $environment_id = null ) {
|
86 |
+
$gateway = $this->get_gateway();
|
87 |
+
// default to current environment
|
88 |
+
if ( is_null( $environment_id ) ) {
|
89 |
+
$environment_id = $this->get_environment_id();
|
90 |
+
}
|
91 |
+
|
92 |
+
// perform the API request to tokenize the payment method if needed
|
93 |
+
if ( ! $response || $this->get_gateway()->tokenize_after_sale() ) {
|
94 |
+
$response = $gateway->get_api()->tokenize_payment_method( $order );
|
95 |
+
}
|
96 |
+
|
97 |
+
if ( $response->transaction_approved() ) {
|
98 |
+
|
99 |
+
// add the token to the order object for processing
|
100 |
+
$token = $response->get_payment_token();
|
101 |
+
$address = new Customer_Address();
|
102 |
+
|
103 |
+
// generate an address from the order
|
104 |
+
$address->set_from_order( $order );
|
105 |
+
|
106 |
+
// store the billing hash on the token for later use in case it needs to be updated
|
107 |
+
$token->set_billing_hash( $address->get_hash() );
|
108 |
+
|
109 |
+
// set the resulting token on the order
|
110 |
+
$order->payment->token = $token->get_id();
|
111 |
+
|
112 |
+
// for credit card transactions add the card type, if known (some gateways return the credit card type as part of the response, others may require it as part of the request, and still others it may never be known)
|
113 |
+
if ( $gateway->is_credit_card_gateway() && $token->get_card_type() ) {
|
114 |
+
$order->payment->card_type = $token->get_card_type();
|
115 |
+
}
|
116 |
+
|
117 |
+
// set the token to the user account
|
118 |
+
if ( $order->get_user_id() ) {
|
119 |
+
$this->add_token( $order->get_user_id(), $token, $environment_id );
|
120 |
+
}
|
121 |
+
|
122 |
+
$order->add_order_note( $this->get_order_note( $token ) );
|
123 |
+
|
124 |
+
// add the standard transaction data
|
125 |
+
$gateway->add_transaction_data( $order, $response );
|
126 |
+
|
127 |
+
// clear any cached tokens
|
128 |
+
if ( $transient_key = $this->get_transient_key( $order->get_user_id() ) ) {
|
129 |
+
delete_transient( $transient_key );
|
130 |
+
}
|
131 |
+
|
132 |
+
} else {
|
133 |
+
|
134 |
+
if ( $response->get_status_code() && $response->get_status_message() ) {
|
135 |
+
/* translators: Placeholders: %1$s - payment request response status code, %2$s - payment request response status message */
|
136 |
+
$message = sprintf( esc_html__( 'Status code %1$s: %2$s', 'woocommerce-square' ), $response->get_status_code(), $response->get_status_message() );
|
137 |
+
} elseif ( $response->get_status_code() ) {
|
138 |
+
/* translators: Placeholders: %s - payment request response status code */
|
139 |
+
$message = sprintf( esc_html__( 'Status code: %s', 'woocommerce-square' ), $response->get_status_code() );
|
140 |
+
} elseif ( $response->get_status_message() ) {
|
141 |
+
/* translators: Placeholders: %s - payment request response status message */
|
142 |
+
$message = sprintf( esc_html__( 'Status message: %s', 'woocommerce-square' ), $response->get_status_message() );
|
143 |
+
} else {
|
144 |
+
$message = esc_html__( 'Unknown Error', 'woocommerce-square' );
|
145 |
+
}
|
146 |
+
|
147 |
+
// add transaction id if there is one
|
148 |
+
if ( $response->get_transaction_id() ) {
|
149 |
+
$message .= ' ' . sprintf( esc_html__( 'Transaction ID %s', 'woocommerce-square' ), $response->get_transaction_id() );
|
150 |
+
}
|
151 |
+
|
152 |
+
throw new \Exception( $message );
|
153 |
+
}
|
154 |
+
|
155 |
+
return $order;
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Adds a payment method and token as user meta.
|
161 |
+
*
|
162 |
+
* @since 3.0.0
|
163 |
+
*
|
164 |
+
* @param int $user_id user identifier
|
165 |
+
* @param Payment_Gateway_Payment_Token $token the token
|
166 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
167 |
+
* @return bool|int false if token not added, user meta ID if added
|
168 |
+
*/
|
169 |
+
public function add_token( $user_id, $token, $environment_id = null ) {
|
170 |
+
|
171 |
+
// default to current environment
|
172 |
+
if ( is_null( $environment_id ) ) {
|
173 |
+
$environment_id = $this->get_environment_id();
|
174 |
+
}
|
175 |
+
|
176 |
+
// get existing tokens
|
177 |
+
$tokens = $this->get_tokens( $user_id, array( 'environment_id' => $environment_id ) );
|
178 |
+
|
179 |
+
// if this token is set as active, mark all others as false
|
180 |
+
if ( $token->is_default() ) {
|
181 |
+
foreach ( array_keys( $tokens ) as $key ) {
|
182 |
+
$tokens[ $key ]->set_default( false );
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
// add the new token
|
187 |
+
$tokens[ $token->get_id() ] = $token;
|
188 |
+
|
189 |
+
// persist the updated tokens
|
190 |
+
return $this->update_tokens( $user_id, $tokens, $environment_id );
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Returns the payment token object identified by $token from the user
|
196 |
+
* identified by $user_id
|
197 |
+
*
|
198 |
+
* @since 3.0.0
|
199 |
+
*
|
200 |
+
* @param int $user_id WordPress user identifier, or 0 for guest
|
201 |
+
* @param string $token payment token
|
202 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
203 |
+
* @return Payment_Gateway_Payment_Token payment token object or null
|
204 |
+
*/
|
205 |
+
public function get_token( $user_id, $token, $environment_id = null ) {
|
206 |
+
|
207 |
+
// default to current environment
|
208 |
+
if ( is_null( $environment_id ) ) {
|
209 |
+
$environment_id = $this->get_environment_id();
|
210 |
+
}
|
211 |
+
|
212 |
+
$tokens = $this->get_tokens( $user_id, array( 'environment_id' => $environment_id ) );
|
213 |
+
|
214 |
+
if ( isset( $tokens[ $token ] ) ) return $tokens[ $token ];
|
215 |
+
|
216 |
+
return null;
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Updates a single token by persisting it to user meta
|
222 |
+
*
|
223 |
+
* @since 3.0.0
|
224 |
+
*
|
225 |
+
* @param int $user_id WP user ID
|
226 |
+
* @param Payment_Gateway_Payment_Token $token token to update
|
227 |
+
* @param string|null $environment_id optional environment ID, defaults to plugin current environment
|
228 |
+
* @return string|int updated user meta ID
|
229 |
+
*/
|
230 |
+
public function update_token( $user_id, $token, $environment_id = null ) {
|
231 |
+
|
232 |
+
// default to current environment
|
233 |
+
if ( null === $environment_id ) {
|
234 |
+
$environment_id = $this->get_environment_id();
|
235 |
+
}
|
236 |
+
|
237 |
+
$tokens = $this->get_tokens( $user_id, array( 'environment_id' => $environment_id ) );
|
238 |
+
|
239 |
+
if ( isset( $tokens[ $token->get_id() ] ) ) {
|
240 |
+
$tokens[ $token->get_id() ] = $token;
|
241 |
+
}
|
242 |
+
|
243 |
+
return $this->update_tokens( $user_id, $tokens, $environment_id );
|
244 |
+
}
|
245 |
+
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Deletes a credit card token from user meta
|
249 |
+
*
|
250 |
+
* @since 3.0.0
|
251 |
+
*
|
252 |
+
* @param int $user_id user identifier
|
253 |
+
* @param Payment_Gateway_Payment_Token|string $token the payment token to delete
|
254 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
255 |
+
* @return bool|int false if not deleted, updated user meta ID if deleted
|
256 |
+
*/
|
257 |
+
public function remove_token( $user_id, $token, $environment_id = null ) {
|
258 |
+
|
259 |
+
// default to current environment
|
260 |
+
if ( is_null( $environment_id ) ) {
|
261 |
+
$environment_id = $this->get_environment_id();
|
262 |
+
}
|
263 |
+
|
264 |
+
// unknown token?
|
265 |
+
if ( ! $this->user_has_token( $user_id, $token, $environment_id ) ) {
|
266 |
+
return false;
|
267 |
+
}
|
268 |
+
|
269 |
+
// get the payment token object as needed
|
270 |
+
if ( ! is_object( $token ) ) {
|
271 |
+
$token = $this->get_token( $user_id, $token, $environment_id );
|
272 |
+
}
|
273 |
+
|
274 |
+
// for direct gateways that allow it, attempt to delete the token from the endpoint
|
275 |
+
if ( $this->get_gateway()->get_api()->supports_remove_tokenized_payment_method() ) {
|
276 |
+
|
277 |
+
try {
|
278 |
+
|
279 |
+
$response = $this->get_gateway()->get_api()->remove_tokenized_payment_method( $token->get_id(), $this->get_gateway()->get_customer_id( $user_id, array( 'environment_id' => $environment_id ) ) );
|
280 |
+
|
281 |
+
if ( ! $response->transaction_approved() && ! $this->should_delete_token( $token, $response ) ) {
|
282 |
+
return false;
|
283 |
+
}
|
284 |
+
|
285 |
+
} catch( \Exception $e ) {
|
286 |
+
|
287 |
+
if ( $this->get_gateway()->debug_log() ) {
|
288 |
+
$this->get_gateway()->get_plugin()->log( $e->getMessage(), $this->get_gateway()->get_id() );
|
289 |
+
}
|
290 |
+
|
291 |
+
return false;
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
return $this->delete_token( $user_id, $token );
|
296 |
+
}
|
297 |
+
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Determines if a token's local meta should be deleted based on an API response.
|
301 |
+
*
|
302 |
+
* @since 3.0.0
|
303 |
+
*
|
304 |
+
* @param Payment_Gateway_Payment_Token $token payment token object
|
305 |
+
* @param Payment_Gateway_API_Response $response API response object
|
306 |
+
* @return bool
|
307 |
+
*/
|
308 |
+
public function should_delete_token( Payment_Gateway_Payment_Token $token, Payment_Gateway_API_Response $response ) {
|
309 |
+
return false;
|
310 |
+
}
|
311 |
+
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Deletes a payment token from user meta.
|
315 |
+
*
|
316 |
+
* @since 3.0.0
|
317 |
+
*
|
318 |
+
* @param int $user_id WordPress user ID
|
319 |
+
* @param Payment_Gateway_Payment_Token $token payment token object
|
320 |
+
* @param string|null $environment_id gateway environment ID
|
321 |
+
* @return bool
|
322 |
+
*/
|
323 |
+
public function delete_token( $user_id, Payment_Gateway_Payment_Token $token, $environment_id = null ) {
|
324 |
+
|
325 |
+
// default to current environment
|
326 |
+
if ( is_null( $environment_id ) ) {
|
327 |
+
$environment_id = $this->get_environment_id();
|
328 |
+
}
|
329 |
+
|
330 |
+
// get existing tokens
|
331 |
+
$tokens = $this->get_tokens( $user_id, array( 'environment_id' => $environment_id ) );
|
332 |
+
|
333 |
+
if ( ! isset( $tokens[ $token->get_id() ] ) ) {
|
334 |
+
return false;
|
335 |
+
}
|
336 |
+
|
337 |
+
unset( $tokens[ $token->get_id() ] );
|
338 |
+
|
339 |
+
// if the deleted card was the default one, make another one the new default
|
340 |
+
if ( $token->is_default() ) {
|
341 |
+
|
342 |
+
foreach ( array_keys( $tokens ) as $key ) {
|
343 |
+
|
344 |
+
$tokens[ $key ]->set_default( true );
|
345 |
+
break;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
// persist the updated tokens
|
350 |
+
return $this->update_tokens( $user_id, $tokens );
|
351 |
+
}
|
352 |
+
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Sets the default token for a user.
|
356 |
+
*
|
357 |
+
* This is shown as "Default Card" in the frontend and will be auto-selected during checkout.
|
358 |
+
*
|
359 |
+
* @since 3.0.0
|
360 |
+
*
|
361 |
+
* @param int $user_id user identifier
|
362 |
+
* @param Payment_Gateway_Payment_Token|string $token the token to make default
|
363 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
364 |
+
* @return string|bool false if not set, updated user meta ID if set
|
365 |
+
*/
|
366 |
+
public function set_default_token( $user_id, $token, $environment_id = null ) {
|
367 |
+
|
368 |
+
// default to current environment
|
369 |
+
if ( is_null( $environment_id ) ) {
|
370 |
+
$environment_id = $this->get_environment_id();
|
371 |
+
}
|
372 |
+
|
373 |
+
// unknown token?
|
374 |
+
if ( ! $this->user_has_token( $user_id, $token ) )
|
375 |
+
return false;
|
376 |
+
|
377 |
+
// get the payment token object as needed
|
378 |
+
if ( ! is_object( $token ) ) {
|
379 |
+
$token = $this->get_token( $user_id, $token, $environment_id );
|
380 |
+
}
|
381 |
+
|
382 |
+
// get existing tokens
|
383 |
+
$tokens = $this->get_tokens( $user_id, array( 'environment_id' => $environment_id ) );
|
384 |
+
|
385 |
+
// mark $token as the only active
|
386 |
+
foreach ( $tokens as $key => $_token ) {
|
387 |
+
|
388 |
+
if ( $token->get_id() == $_token->get_id() ) {
|
389 |
+
$tokens[ $key ]->set_default( true );
|
390 |
+
} else {
|
391 |
+
$tokens[ $key ]->set_default( false );
|
392 |
+
}
|
393 |
+
|
394 |
+
}
|
395 |
+
|
396 |
+
// persist the updated tokens
|
397 |
+
return $this->update_tokens( $user_id, $tokens, $environment_id );
|
398 |
+
|
399 |
+
}
|
400 |
+
|
401 |
+
|
402 |
+
/** Handle all tokens *************************************************************************/
|
403 |
+
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Gets the available payment tokens for a user as an associative array of
|
407 |
+
* payment token to Payment_Gateway_Payment_Token
|
408 |
+
*
|
409 |
+
* @since 3.0.0
|
410 |
+
*
|
411 |
+
* @param int $user_id WordPress user identifier, or 0 for guest
|
412 |
+
* @param array $args optional arguments, can include
|
413 |
+
* `customer_id` - if not provided, this will be looked up based on $user_id
|
414 |
+
* `environment_id` - defaults to plugin current environment
|
415 |
+
* @return array|Payment_Gateway_Payment_Token[] associative array of string token to Payment_Gateway_Payment_Token object
|
416 |
+
*/
|
417 |
+
public function get_tokens( $user_id, $args = array() ) {
|
418 |
+
|
419 |
+
// default to current environment
|
420 |
+
if ( ! isset( $args['environment_id'] ) ) {
|
421 |
+
$args['environment_id'] = $this->get_environment_id();
|
422 |
+
}
|
423 |
+
|
424 |
+
if ( ! isset( $args['customer_id'] ) ) {
|
425 |
+
$args['customer_id'] = $this->get_gateway()->get_customer_id( $user_id, array( 'environment_id' => $args['environment_id'] ) );
|
426 |
+
}
|
427 |
+
|
428 |
+
$environment_id = $args['environment_id'];
|
429 |
+
$customer_id = $args['customer_id'];
|
430 |
+
$transient_key = $this->get_transient_key( $user_id );
|
431 |
+
|
432 |
+
// return tokens cached during a single request
|
433 |
+
if ( isset( $this->tokens[ $environment_id ][ $user_id ] ) ) {
|
434 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
435 |
+
}
|
436 |
+
|
437 |
+
// return tokens cached in transient
|
438 |
+
if ( $transient_key && ( false !== ( $this->tokens[ $environment_id ][ $user_id ] = get_transient( $transient_key ) ) ) ) {
|
439 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
440 |
+
}
|
441 |
+
|
442 |
+
$this->tokens[ $environment_id ][ $user_id ] = array();
|
443 |
+
$tokens = array();
|
444 |
+
|
445 |
+
// retrieve the datastore persisted tokens first, so we have them for
|
446 |
+
// gateways that don't support fetching them over an API, as well as the
|
447 |
+
// default token for those that do
|
448 |
+
if ( $user_id ) {
|
449 |
+
|
450 |
+
$_tokens = get_user_meta( $user_id, $this->get_user_meta_name( $environment_id ), true );
|
451 |
+
|
452 |
+
// from database format
|
453 |
+
if ( is_array( $_tokens ) ) {
|
454 |
+
foreach ( $_tokens as $token => $data ) {
|
455 |
+
$tokens[ $token ] = $this->build_token( $token, $data );
|
456 |
+
}
|
457 |
+
}
|
458 |
+
|
459 |
+
$this->tokens[ $environment_id ][ $user_id ] = $tokens;
|
460 |
+
}
|
461 |
+
|
462 |
+
// if the payment gateway API supports retrieving tokens directly, do so as it's easier to stay synchronized
|
463 |
+
if ( $this->get_gateway()->get_api()->supports_get_tokenized_payment_methods() && $customer_id ) {
|
464 |
+
|
465 |
+
try {
|
466 |
+
|
467 |
+
// retrieve the payment method tokes from the remote API
|
468 |
+
$response = $this->get_gateway()->get_api()->get_tokenized_payment_methods( $customer_id );
|
469 |
+
$this->tokens[ $environment_id ][ $user_id ] = $response->get_payment_tokens();
|
470 |
+
|
471 |
+
// check for a default from the persisted set, if any
|
472 |
+
$default_token = null;
|
473 |
+
foreach ( $tokens as $default_token ) {
|
474 |
+
if ( $default_token->is_default() ) {
|
475 |
+
break;
|
476 |
+
}
|
477 |
+
}
|
478 |
+
|
479 |
+
// mark the corresponding token from the API as the default one
|
480 |
+
if ( $default_token && $default_token->is_default() && isset( $this->tokens[ $environment_id ][ $user_id ][ $default_token->get_id() ] ) ) {
|
481 |
+
$this->tokens[ $environment_id ][ $user_id ][ $default_token->get_id() ]->set_default( true );
|
482 |
+
}
|
483 |
+
|
484 |
+
// merge local token data with remote data, sometimes local data is more robust
|
485 |
+
$this->tokens[ $environment_id ][ $user_id ] = $this->merge_token_data( $tokens, $this->tokens[ $environment_id ][ $user_id ] );
|
486 |
+
|
487 |
+
// persist locally after merging
|
488 |
+
$this->update_tokens( $user_id, $this->tokens[ $environment_id ][ $user_id ], $environment_id );
|
489 |
+
|
490 |
+
} catch( \Exception $e ) {
|
491 |
+
|
492 |
+
// communication or other error
|
493 |
+
|
494 |
+
$this->get_gateway()->add_debug_message( $e->getMessage(), 'error' );
|
495 |
+
|
496 |
+
$this->tokens[ $environment_id ][ $user_id ] = $tokens;
|
497 |
+
}
|
498 |
+
|
499 |
+
}
|
500 |
+
|
501 |
+
// set the payment type image url, if any, for convenience
|
502 |
+
foreach ( $this->tokens[ $environment_id ][ $user_id ] as $key => $token ) {
|
503 |
+
$this->tokens[ $environment_id ][ $user_id ][ $key ]->set_image_url( $this->get_gateway()->get_payment_method_image_url( $token->is_credit_card() ? $token->get_card_type() : 'echeck' ) );
|
504 |
+
}
|
505 |
+
|
506 |
+
if ( $transient_key ) {
|
507 |
+
set_transient( $transient_key, $this->tokens[ $environment_id ][ $user_id ], 60 );
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Direct Payment Gateway Payment Tokens Loaded Action.
|
512 |
+
*
|
513 |
+
* Fired when payment tokens have been completely loaded.
|
514 |
+
*
|
515 |
+
* @since 3.0.0
|
516 |
+
*
|
517 |
+
* @param array $tokens array of Payment_Gateway_Payment_Tokens
|
518 |
+
* @param Payment_Gateway gateway class instance
|
519 |
+
*/
|
520 |
+
do_action( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_payment_tokens_loaded', $this->tokens[ $environment_id ][ $user_id ], $this );
|
521 |
+
|
522 |
+
return $this->tokens[ $environment_id ][ $user_id ];
|
523 |
+
}
|
524 |
+
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Updates the given payment tokens for the identified user, in the database.
|
528 |
+
*
|
529 |
+
* @since 3.0.0
|
530 |
+
*
|
531 |
+
* @param int $user_id WP user ID
|
532 |
+
* @param array $tokens array of tokens
|
533 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
534 |
+
* @return string updated user meta id
|
535 |
+
*/
|
536 |
+
public function update_tokens( $user_id, $tokens, $environment_id = null ) {
|
537 |
+
|
538 |
+
// default to current environment
|
539 |
+
if ( is_null( $environment_id ) ) {
|
540 |
+
$environment_id = $this->get_environment_id();
|
541 |
+
}
|
542 |
+
|
543 |
+
// update the local cache
|
544 |
+
$this->tokens[ $environment_id ][ $user_id ] = $tokens;
|
545 |
+
|
546 |
+
// clear the transient
|
547 |
+
$this->clear_transient( $user_id );
|
548 |
+
|
549 |
+
// persist the updated tokens to the user meta
|
550 |
+
return update_user_meta( $user_id, $this->get_user_meta_name( $environment_id ), $this->format_for_db( $tokens ) );
|
551 |
+
}
|
552 |
+
|
553 |
+
|
554 |
+
|
555 |
+
/** Admin methods *****************************************************************************/
|
556 |
+
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Get the admin token editor instance.
|
560 |
+
*
|
561 |
+
* @since 3.0.0
|
562 |
+
*
|
563 |
+
* @return Payment_Gateway_Admin_Payment_Token_Editor
|
564 |
+
*/
|
565 |
+
public function get_token_editor() {
|
566 |
+
return new Payment_Gateway_Admin_Payment_Token_Editor( $this->get_gateway() );
|
567 |
+
}
|
568 |
+
|
569 |
+
|
570 |
+
/** Conditional methods ***********************************************************************/
|
571 |
+
|
572 |
+
|
573 |
+
/**
|
574 |
+
* Determines if the identified user has the given payment token
|
575 |
+
*
|
576 |
+
* @since 3.0.0
|
577 |
+
*
|
578 |
+
* @param int $user_id WordPress user identifier, or 0 for guest
|
579 |
+
* @param string|Payment_Gateway_Payment_Token $token payment token
|
580 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
581 |
+
* @return bool
|
582 |
+
*/
|
583 |
+
public function user_has_token( $user_id, $token, $environment_id = null ) {
|
584 |
+
|
585 |
+
// default to current environment
|
586 |
+
if ( is_null( $environment_id ) ) {
|
587 |
+
$environment_id = $this->get_environment_id();
|
588 |
+
}
|
589 |
+
|
590 |
+
if ( is_object( $token ) ) {
|
591 |
+
$token = $token->get_id();
|
592 |
+
}
|
593 |
+
|
594 |
+
// token exists?
|
595 |
+
return ! is_null( $this->get_token( $user_id, $token, $environment_id ) );
|
596 |
+
}
|
597 |
+
|
598 |
+
|
599 |
+
/**
|
600 |
+
* Determines if the current payment method should be tokenized.
|
601 |
+
*
|
602 |
+
* Whether requested by customer or otherwise forced. This parameter is passed from
|
603 |
+
* the checkout page/payment form.
|
604 |
+
*
|
605 |
+
* @since 3.0.0
|
606 |
+
*
|
607 |
+
* @return bool
|
608 |
+
*/
|
609 |
+
public function should_tokenize() {
|
610 |
+
|
611 |
+
return Square_Helper::get_post( 'wc-' . $this->get_gateway()->get_id_dasherized() . '-tokenize-payment-method' ) && ! Square_Helper::get_post( 'wc-' . $this->get_gateway()->get_id_dasherized() . '-payment-token' );
|
612 |
+
}
|
613 |
+
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Determines if tokenization should be forced on the checkout page.
|
617 |
+
*
|
618 |
+
* This is most useful to force tokenization for a subscription or pre-orders initial transaction.
|
619 |
+
*
|
620 |
+
* @since 3.0.0
|
621 |
+
*
|
622 |
+
* @return bool
|
623 |
+
*/
|
624 |
+
public function tokenization_forced() {
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Direct Gateway Tokenization Forced Filter.
|
628 |
+
*
|
629 |
+
* Allow actors to indicate that tokenization should be forced for the current
|
630 |
+
* checkout.
|
631 |
+
*
|
632 |
+
* @since 3.0.0
|
633 |
+
*
|
634 |
+
* @param bool $force true to force tokenization, false otherwise
|
635 |
+
* @param Payment_Gateway $this instance
|
636 |
+
*/
|
637 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_tokenization_forced', false, $this->get_gateway() );
|
638 |
+
}
|
639 |
+
|
640 |
+
|
641 |
+
/** Utility methods ***************************************************************************/
|
642 |
+
|
643 |
+
|
644 |
+
/**
|
645 |
+
* Merges remote token data with local tokens.
|
646 |
+
*
|
647 |
+
* Sometimes local tokens can provide additional detail that's not provided remotely.
|
648 |
+
*
|
649 |
+
* @since 3.0.0
|
650 |
+
*
|
651 |
+
* @param array $local_tokens local tokens
|
652 |
+
* @param array $remote_tokens remote tokens
|
653 |
+
* @return array associative array of string token to Payment_Gateway_Payment_Token objects
|
654 |
+
*/
|
655 |
+
protected function merge_token_data( $local_tokens, $remote_tokens ) {
|
656 |
+
|
657 |
+
foreach ( $remote_tokens as &$remote_token ) {
|
658 |
+
|
659 |
+
$remote_token_id = $remote_token->get_id();
|
660 |
+
|
661 |
+
// bail if the remote token doesn't exist locally
|
662 |
+
if ( ! isset( $local_tokens[ $remote_token_id ] ) ) {
|
663 |
+
continue;
|
664 |
+
}
|
665 |
+
|
666 |
+
foreach ( $this->get_merge_attributes() as $attribute ) {
|
667 |
+
|
668 |
+
$get_method = "get_{$attribute}";
|
669 |
+
$set_method = "set_{$attribute}";
|
670 |
+
|
671 |
+
// if the remote token is missing an attribute and the local token has it...
|
672 |
+
if ( ! $remote_token->$get_method() && $local_tokens[ $remote_token_id ]->$get_method() ) {
|
673 |
+
|
674 |
+
// set the attribute on the remote token
|
675 |
+
$remote_token->$set_method( $local_tokens[ $remote_token_id ]->$get_method() );
|
676 |
+
}
|
677 |
+
}
|
678 |
+
}
|
679 |
+
|
680 |
+
return $remote_tokens;
|
681 |
+
}
|
682 |
+
|
683 |
+
|
684 |
+
/**
|
685 |
+
* Returns the attributes that should be used to merge local token data into
|
686 |
+
* a remote token.
|
687 |
+
*
|
688 |
+
* Gateways can override this method to add their own attributes, but must
|
689 |
+
* also include the associated get_*() & set_*() methods in the token class.
|
690 |
+
*
|
691 |
+
* See Authorize.net CIM for an example implementation.
|
692 |
+
*
|
693 |
+
* @since 3.0.0
|
694 |
+
*
|
695 |
+
* @return array associative array of string token to Payment_Gateway_Payment_Token objects
|
696 |
+
*/
|
697 |
+
protected function get_merge_attributes() {
|
698 |
+
|
699 |
+
return array( 'last_four', 'card_type', 'account_type', 'exp_month', 'exp_year', 'nickname' );
|
700 |
+
}
|
701 |
+
|
702 |
+
|
703 |
+
/**
|
704 |
+
* Gets the payment token transient key for the given user, gateway and environment.
|
705 |
+
*
|
706 |
+
* Payment token transients can be disabled by using the filter below.
|
707 |
+
*
|
708 |
+
* @since 3.0.0
|
709 |
+
*
|
710 |
+
* @param string|int $user_id
|
711 |
+
* @return string transient key
|
712 |
+
*/
|
713 |
+
protected function get_transient_key( $user_id = null ) {
|
714 |
+
|
715 |
+
if ( ! $user_id ) {
|
716 |
+
$user_id = get_current_user_id();
|
717 |
+
}
|
718 |
+
|
719 |
+
// ex: wc_square_tokens_<md5 hash of gateway_id, user ID, and environment ID>
|
720 |
+
$key = sprintf( 'wc_square_tokens_%s', md5( $this->get_gateway()->get_id() . '_' . $user_id . '_' . $this->get_environment_id() ) );
|
721 |
+
|
722 |
+
/**
|
723 |
+
* Filter payment tokens transient key
|
724 |
+
*
|
725 |
+
* Warning: this filter should generally only be used to disable token
|
726 |
+
* transients by returning false or an empty string. Setting an incorrect or invalid
|
727 |
+
* transient key (e.g. not keyed to the current user or environment) can
|
728 |
+
* result in unexpected and difficult to debug situations involving tokens.
|
729 |
+
*
|
730 |
+
* filter responsibly!
|
731 |
+
*
|
732 |
+
* @since 3.0.0
|
733 |
+
* @param string $key transient key (must be 45 chars or less)
|
734 |
+
* @param Payment_Gateway $this direct gateway class instance
|
735 |
+
*/
|
736 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_gateway()->get_id() . '_payment_tokens_transient_key', $key, $user_id, $this->get_gateway() );
|
737 |
+
}
|
738 |
+
|
739 |
+
|
740 |
+
/**
|
741 |
+
* Helper method to clear the tokens transient
|
742 |
+
*
|
743 |
+
* TODO: ideally the transient would make use of actions to clear itself
|
744 |
+
* as needed (e.g. when customer IDs are updated/removed), but for now it's
|
745 |
+
* only cleared when the tokens are updated. @MR July 2015
|
746 |
+
*
|
747 |
+
* @since 3.0.0
|
748 |
+
*
|
749 |
+
* @param int|string $user_id
|
750 |
+
*/
|
751 |
+
public function clear_transient( $user_id ) {
|
752 |
+
delete_transient( $this->get_transient_key( $user_id ) );
|
753 |
+
}
|
754 |
+
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Returns the payment token user meta name for persisting the payment tokens.
|
758 |
+
*
|
759 |
+
* Defaults to _wc_{gateway id}_payment_tokens for the production environment,
|
760 |
+
* and _wc_{gateway id}_payment_tokens_{environment} for any other environment.
|
761 |
+
*
|
762 |
+
* NOTE: the gateway id, rather than plugin id, is used by default to create
|
763 |
+
* the meta key for this setting, because it's assumed that in the case of a
|
764 |
+
* plugin having multiple gateways (ie credit card and eCheck) the payment
|
765 |
+
* tokens will be distinct between them
|
766 |
+
*
|
767 |
+
* @since 3.0.0
|
768 |
+
*
|
769 |
+
* @param string|null $environment_id optional environment id, defaults to plugin current environment
|
770 |
+
* @return string payment token user meta name
|
771 |
+
*/
|
772 |
+
public function get_user_meta_name( $environment_id = null ) {
|
773 |
+
|
774 |
+
// default to current environment
|
775 |
+
if ( is_null( $environment_id ) ) {
|
776 |
+
$environment_id = $this->get_environment_id();
|
777 |
+
}
|
778 |
+
|
779 |
+
// leading underscore since this will never be displayed to an admin user in its raw form
|
780 |
+
return $this->get_gateway()->get_order_meta_prefix() . 'payment_tokens' . ( ! $this->get_gateway()->is_production_environment( $environment_id ) ? '_' . $environment_id : '' );
|
781 |
+
}
|
782 |
+
|
783 |
+
|
784 |
+
/**
|
785 |
+
* Gets the order note message when a customer saves their payment method
|
786 |
+
* to their account
|
787 |
+
*
|
788 |
+
* @since 3.0.0
|
789 |
+
*
|
790 |
+
* @param Payment_Gateway_Payment_Token $token the payment token being saved
|
791 |
+
* @return string
|
792 |
+
*/
|
793 |
+
protected function get_order_note( $token ) {
|
794 |
+
|
795 |
+
$gateway = $this->get_gateway();
|
796 |
+
|
797 |
+
$message = '';
|
798 |
+
|
799 |
+
// order note based on gateway type
|
800 |
+
if ( $gateway->is_credit_card_gateway() ) {
|
801 |
+
|
802 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - payment method name (mastercard, bank account, etc), %3$s - last four digits of the card/account, %4$s - card/account expiry date */
|
803 |
+
$message = sprintf( esc_html__( '%1$s Payment Method Saved: %2$s ending in %3$s (expires %4$s)', 'woocommerce-square' ),
|
804 |
+
$gateway->get_method_title(),
|
805 |
+
$token->get_type_full(),
|
806 |
+
$token->get_last_four(),
|
807 |
+
$token->get_exp_date()
|
808 |
+
);
|
809 |
+
|
810 |
+
}
|
811 |
+
|
812 |
+
return $message;
|
813 |
+
}
|
814 |
+
|
815 |
+
|
816 |
+
/**
|
817 |
+
* Returns $tokens in a format suitable for data storage
|
818 |
+
*
|
819 |
+
* @since 3.0.0
|
820 |
+
*
|
821 |
+
* @param array $tokens array of Payment_Gateway_Payment_Token tokens
|
822 |
+
* @return array data storage version of $tokens
|
823 |
+
*/
|
824 |
+
protected function format_for_db( $tokens ) {
|
825 |
+
|
826 |
+
$_tokens = array();
|
827 |
+
|
828 |
+
// to database format
|
829 |
+
foreach ( $tokens as $key => $token ) {
|
830 |
+
$_tokens[ $key ] = $token->to_datastore_format();
|
831 |
+
}
|
832 |
+
|
833 |
+
return $_tokens;
|
834 |
+
}
|
835 |
+
|
836 |
+
|
837 |
+
/**
|
838 |
+
* Get the gateway environment ID.
|
839 |
+
*
|
840 |
+
* @since 3.0.0
|
841 |
+
*
|
842 |
+
* @return string
|
843 |
+
*/
|
844 |
+
protected function get_environment_id() {
|
845 |
+
return $this->environment_id;
|
846 |
+
}
|
847 |
+
|
848 |
+
|
849 |
+
/**
|
850 |
+
* Gets the gateway instance.
|
851 |
+
*
|
852 |
+
* @since 3.0.0
|
853 |
+
*
|
854 |
+
* @return Payment_Gateway gateway instance
|
855 |
+
*/
|
856 |
+
protected function get_gateway() {
|
857 |
+
return $this->gateway;
|
858 |
+
}
|
859 |
+
}
|
includes/Framework/PaymentGateway/Payment_Gateway.php
ADDED
@@ -0,0 +1,3813 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway;
|
4 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
5 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Authorization_Response;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Response;
|
8 |
+
use WooCommerce\Square\Framework\PaymentGateway\ApplePay\Api\Payment_Gateway_Apple_Pay_Payment_Response;
|
9 |
+
use WooCommerce\Square\Framework\PaymentGateway\Handlers\Capture;
|
10 |
+
use WooCommerce\Square\Framework\PaymentGateway\Integrations\Payment_Gateway_Integration_Pre_Orders;
|
11 |
+
use WooCommerce\Square\Framework\PaymentGateway\Integrations\Payment_Gateway_Integration_Subscriptions;
|
12 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Tokens_Handler;
|
13 |
+
use WooCommerce\Square\Plugin;
|
14 |
+
use WooCommerce\Square\Framework as SquareFramework;
|
15 |
+
|
16 |
+
defined( 'ABSPATH' ) or exit;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* WooCommerce Payment Gateway Framework
|
20 |
+
*
|
21 |
+
* @since 3.0.0
|
22 |
+
*/
|
23 |
+
abstract class Payment_Gateway extends \WC_Payment_Gateway {
|
24 |
+
|
25 |
+
|
26 |
+
/** Sends through sale and request for funds to be charged to cardholder's credit card. */
|
27 |
+
const TRANSACTION_TYPE_CHARGE = 'charge';
|
28 |
+
|
29 |
+
/** Sends through a request for funds to be "reserved" on the cardholder's credit card. A standard authorization is reserved for 2-5 days. Reservation times are determined by cardholder's bank. */
|
30 |
+
const TRANSACTION_TYPE_AUTHORIZATION = 'authorization';
|
31 |
+
|
32 |
+
/** The production environment identifier */
|
33 |
+
const ENVIRONMENT_PRODUCTION = 'production';
|
34 |
+
|
35 |
+
/** The test environment identifier */
|
36 |
+
const ENVIRONMENT_TEST = 'test';
|
37 |
+
|
38 |
+
/** Debug mode log to file */
|
39 |
+
const DEBUG_MODE_LOG = 'log';
|
40 |
+
|
41 |
+
/** Debug mode display on checkout */
|
42 |
+
const DEBUG_MODE_CHECKOUT = 'checkout';
|
43 |
+
|
44 |
+
/** Debug mode log to file and display on checkout */
|
45 |
+
const DEBUG_MODE_BOTH = 'both';
|
46 |
+
|
47 |
+
/** Debug mode disabled */
|
48 |
+
const DEBUG_MODE_OFF = 'off';
|
49 |
+
|
50 |
+
/** Credit card payment type */
|
51 |
+
const PAYMENT_TYPE_CREDIT_CARD = 'credit-card';
|
52 |
+
|
53 |
+
/** Products feature */
|
54 |
+
const FEATURE_PRODUCTS = 'products';
|
55 |
+
|
56 |
+
/** Credit card types feature */
|
57 |
+
const FEATURE_CARD_TYPES = 'card_types';
|
58 |
+
|
59 |
+
/** Tokenization feature */
|
60 |
+
const FEATURE_TOKENIZATION = 'tokenization';
|
61 |
+
|
62 |
+
/** Credit Card charge transaction feature */
|
63 |
+
const FEATURE_CREDIT_CARD_CHARGE = 'charge';
|
64 |
+
|
65 |
+
/** Credit Card authorization transaction feature */
|
66 |
+
const FEATURE_CREDIT_CARD_AUTHORIZATION = 'authorization';
|
67 |
+
|
68 |
+
/** Credit Card charge virtual-only orders feature */
|
69 |
+
const FEATURE_CREDIT_CARD_CHARGE_VIRTUAL = 'charge-virtual';
|
70 |
+
|
71 |
+
/** Credit Card capture charge transaction feature */
|
72 |
+
const FEATURE_CREDIT_CARD_CAPTURE = 'capture_charge';
|
73 |
+
|
74 |
+
/** Credit Card partial capture transaction feature */
|
75 |
+
const FEATURE_CREDIT_CARD_PARTIAL_CAPTURE = 'partial_capture';
|
76 |
+
|
77 |
+
/** Display detailed customer decline messages on checkout */
|
78 |
+
const FEATURE_DETAILED_CUSTOMER_DECLINE_MESSAGES = 'customer_decline_messages';
|
79 |
+
|
80 |
+
/** Refunds feature */
|
81 |
+
const FEATURE_REFUNDS = 'refunds';
|
82 |
+
|
83 |
+
/** Voids feature */
|
84 |
+
const FEATURE_VOIDS = 'voids';
|
85 |
+
|
86 |
+
/** Payment Form feature */
|
87 |
+
const FEATURE_PAYMENT_FORM = 'payment_form';
|
88 |
+
|
89 |
+
/** Customer ID feature */
|
90 |
+
const FEATURE_CUSTOMER_ID = 'customer_id';
|
91 |
+
|
92 |
+
/** Add new payment method feature */
|
93 |
+
const FEATURE_ADD_PAYMENT_METHOD = 'add_payment_method';
|
94 |
+
|
95 |
+
/** Apple Pay feature */
|
96 |
+
const FEATURE_APPLE_PAY = 'apple_pay';
|
97 |
+
|
98 |
+
/** Admin token editor feature */
|
99 |
+
const FEATURE_TOKEN_EDITOR = 'token_editor';
|
100 |
+
|
101 |
+
/** Subscriptions integration ID */
|
102 |
+
const INTEGRATION_SUBSCRIPTIONS = 'subscriptions';
|
103 |
+
|
104 |
+
/** Pre-orders integration ID */
|
105 |
+
const INTEGRATION_PRE_ORDERS = 'pre_orders';
|
106 |
+
|
107 |
+
/** @var Payment_Gateway_Plugin the parent plugin class */
|
108 |
+
private $plugin;
|
109 |
+
|
110 |
+
/** @var string payment type, one of 'credit-card' */
|
111 |
+
private $payment_type;
|
112 |
+
|
113 |
+
/** @var array associative array of environment id to display name, defaults to 'production' => 'Production' */
|
114 |
+
private $environments;
|
115 |
+
|
116 |
+
/** @var array associative array of card type to display name */
|
117 |
+
private $available_card_types;
|
118 |
+
|
119 |
+
/** @var array optional array of currency codes this gateway is allowed for */
|
120 |
+
protected $currencies;
|
121 |
+
|
122 |
+
/** @var string configuration option: the transaction environment, one of $this->environments keys */
|
123 |
+
private $environment;
|
124 |
+
|
125 |
+
/** @var string configuration option: the type of transaction, whether purchase or authorization, defaults to 'charge' */
|
126 |
+
private $transaction_type;
|
127 |
+
|
128 |
+
/** @var string configuration option: whether transactions should always be charged if the order is virtual-only, defaults to 'no' */
|
129 |
+
private $charge_virtual_orders;
|
130 |
+
|
131 |
+
/** @var string configuration option: whether orders can be partially captured multiple times */
|
132 |
+
private $enable_partial_capture;
|
133 |
+
|
134 |
+
/** @var string configuration option: whether orders are captured when switched to a "paid" status */
|
135 |
+
private $enable_paid_capture;
|
136 |
+
|
137 |
+
/** @var array configuration option: card types to show images for */
|
138 |
+
private $card_types;
|
139 |
+
|
140 |
+
/** @var string configuration option: indicates whether a Card Security Code field will be presented on checkout, either 'yes' or 'no' */
|
141 |
+
private $enable_csc;
|
142 |
+
|
143 |
+
/** @var string configuration option: indicates whether a Card Security Code field will be presented for saved cards at checkout, either 'yes' or 'no' */
|
144 |
+
private $enable_token_csc;
|
145 |
+
|
146 |
+
/** @var string configuration option: indicates whether tokenization is enabled, either 'yes' or 'no' */
|
147 |
+
private $tokenization;
|
148 |
+
|
149 |
+
/** @var string configuration option: indicates whether detailed customer decline messages should be displayed at checkout, either 'yes' or 'no' */
|
150 |
+
private $enable_customer_decline_messages;
|
151 |
+
|
152 |
+
/** @var string configuration option: 4 options for debug mode - off, checkout, log, both */
|
153 |
+
private $debug_mode;
|
154 |
+
|
155 |
+
/** @var string configuration option: whether to use a sibling gateway's connection/authentication settings */
|
156 |
+
private $inherit_settings;
|
157 |
+
|
158 |
+
/** @var array of shared setting names, if any. */
|
159 |
+
private $shared_settings = array();
|
160 |
+
|
161 |
+
/** @var Payment_Gateway_Payment_Tokens_Handler payment tokens handler instance */
|
162 |
+
protected $payment_tokens_handler;
|
163 |
+
|
164 |
+
/** @var Payment_Gateway\Handlers\Capture capture handler instance */
|
165 |
+
protected $capture_handler;
|
166 |
+
|
167 |
+
/** @var array of Payment_Gateway_Integration objects for Subscriptions, Pre-Orders, etc. */
|
168 |
+
protected $integrations;
|
169 |
+
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Initialize the gateway
|
173 |
+
*
|
174 |
+
* Args:
|
175 |
+
*
|
176 |
+
* + `method_title` - string admin method title, ie 'Intuit QBMS', defaults to 'Settings'
|
177 |
+
* + `method_description` - string admin method description, defaults to ''
|
178 |
+
* + `supports` - array list of supported gateway features, possible values include:
|
179 |
+
* 'products', 'card_types', 'tokenziation', 'charge', 'authorization', 'subscriptions',
|
180 |
+
* 'subscription_suspension', 'subscription_cancellation', 'subscription_reactivation',
|
181 |
+
* 'subscription_amount_changes', 'subscription_date_changes', 'subscription_payment_method_change',
|
182 |
+
* 'customer_decline_messages'
|
183 |
+
* Defaults to 'products', 'charge' (credit-card gateways only)
|
184 |
+
* + `payment_type` - 'credit-card'
|
185 |
+
* + `card_types` - array associative array of card type to display name, used if the payment_type is 'credit-card' and the 'card_types' feature is supported. Defaults to:
|
186 |
+
* 'VISA' => 'Visa', 'MC' => 'MasterCard', 'AMEX' => 'American Express', 'DISC' => 'Discover', 'DINERS' => 'Diners', 'JCB' => 'JCB'
|
187 |
+
* + `environments` - associative array of environment id to display name, merged with default of 'production' => 'Production'
|
188 |
+
* + `currencies` - array of currency codes this gateway is allowed for, defaults to plugin accepted currencies
|
189 |
+
* + `countries` - array of two-letter country codes this gateway is allowed for, defaults to all
|
190 |
+
* + `shared_settings` - array of shared setting names, if any.
|
191 |
+
*
|
192 |
+
* @since 3.0.0
|
193 |
+
* @param string $id the gateway id
|
194 |
+
* @param Payment_Gateway_Plugin $plugin the parent plugin class
|
195 |
+
* @param array $args gateway arguments
|
196 |
+
*/
|
197 |
+
public function __construct( $id, $plugin, $args ) {
|
198 |
+
|
199 |
+
// first setup the gateway and payment type for this gateway
|
200 |
+
$this->payment_type = isset( $args['payment_type'] ) ? $args['payment_type'] : self::PAYMENT_TYPE_CREDIT_CARD;
|
201 |
+
|
202 |
+
// default credit card gateways to supporting 'charge' transaction type, this could be overridden by the 'supports' constructor parameter to include (or only support) authorization
|
203 |
+
if ( $this->is_credit_card_gateway() ) {
|
204 |
+
$this->add_support( self::FEATURE_CREDIT_CARD_CHARGE );
|
205 |
+
}
|
206 |
+
|
207 |
+
// required fields
|
208 |
+
$this->id = $id; // @see WC_Payment_Gateway::$id
|
209 |
+
|
210 |
+
$this->plugin = $plugin;
|
211 |
+
// kind of sucks, but we need to register back to the plugin because
|
212 |
+
// there's no other way of grabbing existing gateways so as to avoid
|
213 |
+
// double-instantiation errors (esp for shared settings)
|
214 |
+
$this->get_plugin()->set_gateway( $id, $this );
|
215 |
+
|
216 |
+
// optional parameters
|
217 |
+
if ( isset( $args['method_title'] ) ) {
|
218 |
+
$this->method_title = $args['method_title']; // @see WC_Settings_API::$method_title
|
219 |
+
}
|
220 |
+
if ( isset( $args['method_description'] ) ) {
|
221 |
+
$this->method_description = $args['method_description']; // @see WC_Settings_API::$method_description
|
222 |
+
}
|
223 |
+
if ( isset( $args['supports'] ) ) {
|
224 |
+
$this->set_supports( $args['supports'] );
|
225 |
+
}
|
226 |
+
if ( isset( $args['card_types'] ) ) {
|
227 |
+
$this->available_card_types = $args['card_types'];
|
228 |
+
}
|
229 |
+
if ( isset( $args['environments'] ) ) {
|
230 |
+
$this->environments = array_merge( $this->get_environments(), $args['environments'] );
|
231 |
+
}
|
232 |
+
if ( isset( $args['countries'] ) ) {
|
233 |
+
$this->countries = $args['countries']; // @see WC_Payment_Gateway::$countries
|
234 |
+
}
|
235 |
+
if ( isset( $args['shared_settings'] ) ) {
|
236 |
+
$this->shared_settings = $args['shared_settings'];
|
237 |
+
}
|
238 |
+
if ( isset( $args['currencies'] ) ) {
|
239 |
+
$this->currencies = $args['currencies'];
|
240 |
+
} else {
|
241 |
+
$this->currencies = $this->get_plugin()->get_accepted_currencies();
|
242 |
+
}
|
243 |
+
if ( isset( $args['order_button_text'] ) ) {
|
244 |
+
$this->order_button_text = $args['order_button_text'];
|
245 |
+
} else {
|
246 |
+
$this->order_button_text = $this->get_order_button_text();
|
247 |
+
}
|
248 |
+
|
249 |
+
// always want to render the field area, even for gateways with no fields, so we can display messages @see WC_Payment_Gateway::$has_fields
|
250 |
+
$this->has_fields = true;
|
251 |
+
|
252 |
+
// default icon filter @see WC_Payment_Gateway::$icon
|
253 |
+
$this->icon = apply_filters( 'wc_' . $this->get_id() . '_icon', '' );
|
254 |
+
|
255 |
+
// Load the form fields
|
256 |
+
$this->init_form_fields();
|
257 |
+
|
258 |
+
// initialize and load the settings
|
259 |
+
$this->init_settings();
|
260 |
+
|
261 |
+
$this->load_settings();
|
262 |
+
|
263 |
+
$this->init_payment_tokens_handler();
|
264 |
+
|
265 |
+
$this->init_integrations();
|
266 |
+
|
267 |
+
// initialize the capture handler
|
268 |
+
$this->init_capture_handler();
|
269 |
+
|
270 |
+
// pay page fallback
|
271 |
+
$this->add_pay_page_handler();
|
272 |
+
|
273 |
+
// filter order received text for held orders
|
274 |
+
add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'maybe_render_held_order_received_text' ), 10, 2 );
|
275 |
+
|
276 |
+
// admin only
|
277 |
+
if ( is_admin() ) {
|
278 |
+
|
279 |
+
// save settings
|
280 |
+
add_action( 'woocommerce_update_options_payment_gateways_' . $this->get_id(), array( $this, 'process_admin_options' ) );
|
281 |
+
}
|
282 |
+
|
283 |
+
// Enqueue the necessary scripts & styles
|
284 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
285 |
+
|
286 |
+
// add API request logging
|
287 |
+
$this->add_api_request_logging();
|
288 |
+
|
289 |
+
// add milestone action hooks
|
290 |
+
$this->add_milestone_hooks();
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Adds the various milestone hooks like "payment processed".
|
296 |
+
*
|
297 |
+
* @since 3.0.0
|
298 |
+
*/
|
299 |
+
protected function add_milestone_hooks() {
|
300 |
+
|
301 |
+
$plugin = $this->get_plugin();
|
302 |
+
|
303 |
+
// first successful payment
|
304 |
+
add_action( 'wc_payment_gateway_' . $this->get_id() . '_payment_processed', function( $order ) use ( &$plugin ) {
|
305 |
+
$plugin->get_lifecycle_handler()->trigger_milestone( 'payment-processed', __( 'you successfully processed a payment!', 'woocommerce-square' ) );
|
306 |
+
} );
|
307 |
+
|
308 |
+
// first successful refund
|
309 |
+
add_action( 'wc_payment_gateway_' . $this->get_id() . '_refund_processed', function( $order ) use ( &$plugin ) {
|
310 |
+
$plugin->get_lifecycle_handler()->trigger_milestone( 'refund-processed', __( 'you successfully processed a refund!', 'woocommerce-square' ) );
|
311 |
+
} );
|
312 |
+
}
|
313 |
+
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Loads the plugin configuration settings
|
317 |
+
*
|
318 |
+
* @since 3.0.0
|
319 |
+
*/
|
320 |
+
public function load_settings() {
|
321 |
+
|
322 |
+
// define user set variables
|
323 |
+
foreach ( $this->settings as $setting_key => $setting ) {
|
324 |
+
$this->$setting_key = $setting;
|
325 |
+
}
|
326 |
+
|
327 |
+
// inherit settings from sibling gateway(s)
|
328 |
+
if ( $this->inherit_settings() ) {
|
329 |
+
$this->load_shared_settings();
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Loads any shared settings from sibling gateways.
|
336 |
+
*
|
337 |
+
* @since 3.0.0
|
338 |
+
*/
|
339 |
+
protected function load_shared_settings() {
|
340 |
+
|
341 |
+
// get any other sibling gateways
|
342 |
+
$other_gateway_ids = array_diff( $this->get_plugin()->get_gateway_ids(), array( $this->get_id() ) );
|
343 |
+
|
344 |
+
// determine if any sibling gateways have any configured shared settings
|
345 |
+
foreach ( $other_gateway_ids as $other_gateway_id ) {
|
346 |
+
|
347 |
+
$other_gateway_settings = $this->get_plugin()->get_gateway_settings( $other_gateway_id );
|
348 |
+
|
349 |
+
// if the other gateway isn't also trying to inherit settings...
|
350 |
+
if ( ! isset( $other_gateway_settings['inherit_settings'] ) || 'no' === $other_gateway_settings['inherit_settings'] ) {
|
351 |
+
|
352 |
+
// load the other gateway so we can access the shared settings properly
|
353 |
+
$other_gateway = $this->get_plugin()->get_gateway( $other_gateway_id );
|
354 |
+
|
355 |
+
// skip this gateway if it isn't meant to share its settings
|
356 |
+
if ( ! $other_gateway->share_settings() ) {
|
357 |
+
continue;
|
358 |
+
}
|
359 |
+
|
360 |
+
foreach ( $this->shared_settings as $setting_key ) {
|
361 |
+
$this->$setting_key = $other_gateway->$setting_key;
|
362 |
+
}
|
363 |
+
}
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Enqueue the necessary scripts & styles for the gateway, including the
|
370 |
+
* payment form assets (if supported) and any gateway-specific assets.
|
371 |
+
*
|
372 |
+
* @since 3.0.0
|
373 |
+
*/
|
374 |
+
public function enqueue_scripts() {
|
375 |
+
|
376 |
+
if ( ! $this->is_available() ) {
|
377 |
+
return;
|
378 |
+
}
|
379 |
+
|
380 |
+
// payment form assets
|
381 |
+
if ( $this->supports_payment_form() ) {
|
382 |
+
|
383 |
+
$this->enqueue_payment_form_assets();
|
384 |
+
}
|
385 |
+
|
386 |
+
// gateway-specific assets
|
387 |
+
$this->enqueue_gateway_assets();
|
388 |
+
}
|
389 |
+
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Enqueue the payment form JS, CSS, and localized
|
393 |
+
* JS params
|
394 |
+
*
|
395 |
+
* @since 3.0.0
|
396 |
+
*/
|
397 |
+
protected function enqueue_payment_form_assets() {
|
398 |
+
|
399 |
+
// bail if on my account page and *not* on add payment method page
|
400 |
+
if ( is_account_page() && ! is_add_payment_method_page() ) {
|
401 |
+
return;
|
402 |
+
}
|
403 |
+
|
404 |
+
$handle = 'wc-square-payment-gateway-payment-form';
|
405 |
+
|
406 |
+
// Frontend JS
|
407 |
+
wp_enqueue_script( $handle, $this->get_plugin()->get_plugin_url() . '/assets/js/frontend/' . $handle . '.min.js', array( 'jquery-payment' ), Plugin::VERSION, true );
|
408 |
+
|
409 |
+
// Frontend CSS
|
410 |
+
wp_enqueue_style( $handle, $this->get_plugin()->get_plugin_url() . '/assets/css/frontend/' . $handle . '.min.css', array(), Plugin::VERSION );
|
411 |
+
|
412 |
+
// localized JS params
|
413 |
+
$this->localize_script( $handle, $this->get_payment_form_js_localized_script_params() );
|
414 |
+
}
|
415 |
+
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Returns an array of JS script params to localize for the
|
419 |
+
* payment form JS. Generally used for i18n purposes.
|
420 |
+
*
|
421 |
+
* @since 3.0.0
|
422 |
+
* @return array associative array of param name to value
|
423 |
+
*/
|
424 |
+
protected function get_payment_form_js_localized_script_params() {
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Payment Form JS Localized Script Params Filter.
|
428 |
+
*
|
429 |
+
* Allow actors to modify the JS localized script params for the
|
430 |
+
* payment form.
|
431 |
+
*
|
432 |
+
* @since 3.0.0
|
433 |
+
* @param array $params
|
434 |
+
* @return array
|
435 |
+
*/
|
436 |
+
return apply_filters( 'sv_wc_payment_gateway_payment_form_js_localized_script_params', array(
|
437 |
+
'card_number_missing' => esc_html__( 'Card number is missing', 'woocommerce-square' ),
|
438 |
+
'card_number_invalid' => esc_html__( 'Card number is invalid', 'woocommerce-square' ),
|
439 |
+
'card_number_digits_invalid' => esc_html__( 'Card number is invalid (only digits allowed)', 'woocommerce-square' ),
|
440 |
+
'card_number_length_invalid' => esc_html__( 'Card number is invalid (wrong length)', 'woocommerce-square' ),
|
441 |
+
'cvv_missing' => esc_html__( 'Card security code is missing', 'woocommerce-square' ),
|
442 |
+
'cvv_digits_invalid' => esc_html__( 'Card security code is invalid (only digits are allowed)', 'woocommerce-square' ),
|
443 |
+
'cvv_length_invalid' => esc_html__( 'Card security code is invalid (must be 3 or 4 digits)', 'woocommerce-square' ),
|
444 |
+
'card_exp_date_invalid' => esc_html__( 'Card expiration date is invalid', 'woocommerce-square' ),
|
445 |
+
'check_number_digits_invalid' => esc_html__( 'Check Number is invalid (only digits are allowed)', 'woocommerce-square' ),
|
446 |
+
'check_number_missing' => esc_html__( 'Check Number is missing', 'woocommerce-square' ),
|
447 |
+
'drivers_license_state_missing' => esc_html__( 'Drivers license state is missing', 'woocommerce-square' ),
|
448 |
+
'drivers_license_number_missing' => esc_html__( 'Drivers license number is missing', 'woocommerce-square' ),
|
449 |
+
'drivers_license_number_invalid' => esc_html__( 'Drivers license number is invalid', 'woocommerce-square' ),
|
450 |
+
'account_number_missing' => esc_html__( 'Account Number is missing', 'woocommerce-square' ),
|
451 |
+
'account_number_invalid' => esc_html__( 'Account Number is invalid (only digits are allowed)', 'woocommerce-square' ),
|
452 |
+
'account_number_length_invalid' => esc_html__( 'Account number is invalid (must be between 5 and 17 digits)', 'woocommerce-square' ),
|
453 |
+
'routing_number_missing' => esc_html__( 'Routing Number is missing', 'woocommerce-square' ),
|
454 |
+
'routing_number_digits_invalid' => esc_html__( 'Routing Number is invalid (only digits are allowed)', 'woocommerce-square' ),
|
455 |
+
'routing_number_length_invalid' => esc_html__( 'Routing number is invalid (must be 9 digits)', 'woocommerce-square' ),
|
456 |
+
) );
|
457 |
+
}
|
458 |
+
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Enqueue the gateway-specific assets if present, including JS, CSS, and
|
462 |
+
* localized script params
|
463 |
+
*
|
464 |
+
* @since 3.0.0
|
465 |
+
*/
|
466 |
+
protected function enqueue_gateway_assets() {
|
467 |
+
|
468 |
+
$handle = $this->get_gateway_js_handle();
|
469 |
+
$js_path = $this->get_plugin()->get_plugin_path() . '/assets/js/frontend/' . $handle . '.min.js';
|
470 |
+
$css_path = $this->get_plugin()->get_plugin_path() . '/assets/css/frontend/' . $handle . '.min.css';
|
471 |
+
|
472 |
+
// JS
|
473 |
+
if ( is_readable( $js_path ) ) {
|
474 |
+
|
475 |
+
$js_url = $this->get_plugin()->get_plugin_url() . '/assets/js/frontend/' . $handle . '.min.js';
|
476 |
+
|
477 |
+
/**
|
478 |
+
* Concrete Payment Gateway JS URL
|
479 |
+
*
|
480 |
+
* Allow actors to modify the URL used when loading a concrete
|
481 |
+
* payment gateway's javascript.
|
482 |
+
*
|
483 |
+
* @since 3.0.0
|
484 |
+
* @param string $js_url JS asset URL
|
485 |
+
* @return string
|
486 |
+
*/
|
487 |
+
$js_url = apply_filters( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_javascript_url', $js_url );
|
488 |
+
|
489 |
+
wp_enqueue_script( $handle, $js_url, array(), $this->get_plugin()->get_version(), true );
|
490 |
+
}
|
491 |
+
|
492 |
+
// CSS
|
493 |
+
if ( is_readable( $css_path ) ) {
|
494 |
+
|
495 |
+
$css_url = $this->get_plugin()->get_plugin_url() . '/assets/css/frontend/' . $handle . '.min.css';
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Concrete Payment Gateway CSS URL
|
499 |
+
*
|
500 |
+
* Allow actors to modify the URL used when loading a concrete payment
|
501 |
+
* gateway's CSS.
|
502 |
+
*
|
503 |
+
* @since 3.0.0
|
504 |
+
* @param string $css_url CSS asset URL
|
505 |
+
* @return string
|
506 |
+
*/
|
507 |
+
$css_url = apply_filters( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_css_url', $css_url );
|
508 |
+
|
509 |
+
wp_enqueue_style( $handle, $css_url, array(), $this->get_plugin()->get_version() );
|
510 |
+
}
|
511 |
+
}
|
512 |
+
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Return the gateway-specifics JS script handle. This is used for:
|
516 |
+
*
|
517 |
+
* + enqueuing the script
|
518 |
+
* + the localized JS script param object name
|
519 |
+
*
|
520 |
+
* Defaults to 'wc-<plugin ID dasherized>'.
|
521 |
+
*
|
522 |
+
* @since 3.0.0
|
523 |
+
* @return string
|
524 |
+
*/
|
525 |
+
protected function get_gateway_js_handle() {
|
526 |
+
|
527 |
+
return 'wc-' . $this->get_plugin()->get_id_dasherized();
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* Localize a script once. Gateway plugins that have multiple gateways should
|
532 |
+
* only have their params localized once.
|
533 |
+
*
|
534 |
+
* @since 3.0.0
|
535 |
+
* @param string $handle script handle to localize
|
536 |
+
* @param array $params script params to localize
|
537 |
+
*/
|
538 |
+
protected function localize_script( $handle, $params ) {
|
539 |
+
|
540 |
+
// If the script isn't loaded, bail
|
541 |
+
if ( ! wp_script_is( $handle, 'enqueued' ) ) {
|
542 |
+
return;
|
543 |
+
}
|
544 |
+
|
545 |
+
global $wp_scripts;
|
546 |
+
|
547 |
+
$object_name = str_replace( '-', '_', $handle ) . '_params';
|
548 |
+
|
549 |
+
// If the plugin's JS params already exists in the localized data, bail
|
550 |
+
if ( $wp_scripts instanceof \WP_Scripts && strpos( $wp_scripts->get_data( $handle, 'data' ), $object_name ) ) {
|
551 |
+
return;
|
552 |
+
}
|
553 |
+
|
554 |
+
wp_localize_script( $handle, $object_name, $params );
|
555 |
+
}
|
556 |
+
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Returns true if on the pay page and this is the currently selected gateway
|
560 |
+
*
|
561 |
+
* @since 3.0.0
|
562 |
+
*
|
563 |
+
* @return null|bool true if on pay page and is currently selected gateways, false if on pay page and not the selected gateway, null otherwise
|
564 |
+
*/
|
565 |
+
public function is_pay_page_gateway() {
|
566 |
+
|
567 |
+
if ( is_checkout_pay_page() ) {
|
568 |
+
|
569 |
+
$order_id = $this->get_checkout_pay_page_order_id();
|
570 |
+
|
571 |
+
if ( $order_id ) {
|
572 |
+
$order = wc_get_order( $order_id );
|
573 |
+
|
574 |
+
return Order_Compatibility::get_prop( $order, 'payment_method' ) === $this->get_id();
|
575 |
+
}
|
576 |
+
|
577 |
+
}
|
578 |
+
|
579 |
+
return null;
|
580 |
+
}
|
581 |
+
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Gets the order button text:
|
585 |
+
*
|
586 |
+
* Direct gateway: "Place order"
|
587 |
+
* Redirect/Hosted gateway: "Continue"
|
588 |
+
*
|
589 |
+
* @since 3.0.0
|
590 |
+
*/
|
591 |
+
protected function get_order_button_text() {
|
592 |
+
|
593 |
+
$text = $this->is_hosted_gateway() ? esc_html__( 'Continue', 'woocommerce-square' ) : esc_html__( 'Place order', 'woocommerce-square' );
|
594 |
+
|
595 |
+
/**
|
596 |
+
* Payment Gateway Place Order Button Text Filter.
|
597 |
+
*
|
598 |
+
* Allow actors to modify the "place order" button text.
|
599 |
+
*
|
600 |
+
* @since 3.0.0
|
601 |
+
* @param string $text button text
|
602 |
+
* @param Payment_Gateway $this instance
|
603 |
+
*/
|
604 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_order_button_text', $text, $this );
|
605 |
+
}
|
606 |
+
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Adds a default simple pay page handler
|
610 |
+
*
|
611 |
+
* @since 3.0.0
|
612 |
+
*/
|
613 |
+
protected function add_pay_page_handler() {
|
614 |
+
add_action( 'woocommerce_receipt_' . $this->get_id(), array( $this, 'payment_page' ) );
|
615 |
+
}
|
616 |
+
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Render a simple payment page
|
620 |
+
*
|
621 |
+
* @since 3.0.0
|
622 |
+
* @param int $order_id identifies the order
|
623 |
+
*/
|
624 |
+
public function payment_page( $order_id ) {
|
625 |
+
echo '<p>' . esc_html__( 'Thank you for your order.', 'woocommerce-square' ) . '</p>';
|
626 |
+
}
|
627 |
+
|
628 |
+
|
629 |
+
/** Payment Form Feature **************************************************/
|
630 |
+
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Returns true if the gateway supports the payment form feature
|
634 |
+
*
|
635 |
+
* @since 3.0.0
|
636 |
+
* @return bool
|
637 |
+
*/
|
638 |
+
public function supports_payment_form() {
|
639 |
+
|
640 |
+
return $this->supports( self::FEATURE_PAYMENT_FORM );
|
641 |
+
}
|
642 |
+
|
643 |
+
|
644 |
+
/**
|
645 |
+
* Render the payment fields
|
646 |
+
*
|
647 |
+
* @since 3.0.0
|
648 |
+
* @see WC_Payment_Gateway::payment_fields()
|
649 |
+
* @see Payment_Gateway_Payment_Form class
|
650 |
+
*/
|
651 |
+
public function payment_fields() {
|
652 |
+
|
653 |
+
if ( $this->supports_payment_form() ) {
|
654 |
+
|
655 |
+
$this->get_payment_form_instance()->render();
|
656 |
+
|
657 |
+
} else {
|
658 |
+
|
659 |
+
parent::payment_fields();
|
660 |
+
}
|
661 |
+
}
|
662 |
+
|
663 |
+
|
664 |
+
/**
|
665 |
+
* Gets the payment form class instance.
|
666 |
+
*
|
667 |
+
* @since 3.0.0
|
668 |
+
*
|
669 |
+
* @return Payment_Gateway_Payment_Form
|
670 |
+
*/
|
671 |
+
public function get_payment_form_instance() {
|
672 |
+
|
673 |
+
return new Payment_Gateway_Payment_Form( $this );
|
674 |
+
}
|
675 |
+
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Get the payment form field defaults, primarily for gateways to override
|
679 |
+
* and set dummy credit card info when in the test environment
|
680 |
+
*
|
681 |
+
* @since 3.0.0
|
682 |
+
* @return array
|
683 |
+
*/
|
684 |
+
public function get_payment_method_defaults() {
|
685 |
+
|
686 |
+
assert( $this->supports_payment_form() );
|
687 |
+
|
688 |
+
$defaults = array(
|
689 |
+
'account-number' => '',
|
690 |
+
'routing-number' => '',
|
691 |
+
'expiry' => '',
|
692 |
+
'csc' => '',
|
693 |
+
);
|
694 |
+
|
695 |
+
if ( $this->is_test_environment() ) {
|
696 |
+
$defaults['expiry'] = '01/' . ( date( 'y' ) + 1 );
|
697 |
+
$defaults['csc'] = '123';
|
698 |
+
}
|
699 |
+
|
700 |
+
return $defaults;
|
701 |
+
}
|
702 |
+
|
703 |
+
|
704 |
+
/** Tokenization **************************************************/
|
705 |
+
|
706 |
+
|
707 |
+
/**
|
708 |
+
* Initialize payment tokens handler.
|
709 |
+
*
|
710 |
+
* @since 3.0.0
|
711 |
+
*/
|
712 |
+
protected function init_payment_tokens_handler() {
|
713 |
+
|
714 |
+
$this->payment_tokens_handler = $this->build_payment_tokens_handler();
|
715 |
+
}
|
716 |
+
|
717 |
+
|
718 |
+
/**
|
719 |
+
* Gets the payment tokens handler instance.
|
720 |
+
*
|
721 |
+
* Concrete classes can override this method to return a custom implementation.
|
722 |
+
*
|
723 |
+
* @since 3.0.0
|
724 |
+
*
|
725 |
+
* @return Payment_Gateway_Payment_Tokens_Handler
|
726 |
+
*/
|
727 |
+
protected function build_payment_tokens_handler() {
|
728 |
+
return new Payment_Gateway_Payment_Tokens_Handler( $this );
|
729 |
+
}
|
730 |
+
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Gets the payment tokens handler instance.
|
734 |
+
*
|
735 |
+
* @since 3.0.0
|
736 |
+
*
|
737 |
+
* @return Payment_Gateway_Payment_Tokens_Handler
|
738 |
+
*/
|
739 |
+
public function get_payment_tokens_handler() {
|
740 |
+
|
741 |
+
return $this->payment_tokens_handler;
|
742 |
+
}
|
743 |
+
|
744 |
+
|
745 |
+
/**
|
746 |
+
* Determines if tokenization takes place prior to transaction processing.
|
747 |
+
*
|
748 |
+
* @since 3.0.0
|
749 |
+
*
|
750 |
+
* @return bool
|
751 |
+
*/
|
752 |
+
public function tokenize_before_sale() {
|
753 |
+
return false;
|
754 |
+
}
|
755 |
+
|
756 |
+
|
757 |
+
/**
|
758 |
+
* Determines tokenization takes place during a transaction request.
|
759 |
+
*
|
760 |
+
* @since 3.0.0
|
761 |
+
*
|
762 |
+
* @return bool
|
763 |
+
*/
|
764 |
+
public function tokenize_with_sale() {
|
765 |
+
return false;
|
766 |
+
}
|
767 |
+
|
768 |
+
|
769 |
+
/**
|
770 |
+
* Determines tokenization takes place after a transaction request.
|
771 |
+
*
|
772 |
+
* @since 3.0.0
|
773 |
+
*
|
774 |
+
* @return bool
|
775 |
+
*/
|
776 |
+
public function tokenize_after_sale() {
|
777 |
+
return false;
|
778 |
+
}
|
779 |
+
|
780 |
+
|
781 |
+
/**
|
782 |
+
* Determines if the gateway supports the admin token editor feature.
|
783 |
+
*
|
784 |
+
* @since 3.0.0
|
785 |
+
*
|
786 |
+
* @return bool
|
787 |
+
*/
|
788 |
+
public function supports_token_editor() {
|
789 |
+
return $this->supports( self::FEATURE_TOKEN_EDITOR );
|
790 |
+
}
|
791 |
+
|
792 |
+
|
793 |
+
/** Integrations Feature **************************************************/
|
794 |
+
|
795 |
+
|
796 |
+
/**
|
797 |
+
* Initializes supported integrations.
|
798 |
+
*
|
799 |
+
* @since 3.0.0
|
800 |
+
*/
|
801 |
+
public function init_integrations() {
|
802 |
+
|
803 |
+
if ( $this->supports_subscriptions() ) {
|
804 |
+
$this->integrations[ self::INTEGRATION_SUBSCRIPTIONS ] = $this->build_subscriptions_integration();
|
805 |
+
}
|
806 |
+
|
807 |
+
if ( $this->supports_pre_orders() ) {
|
808 |
+
$this->integrations[ self::INTEGRATION_PRE_ORDERS ] = $this->build_pre_orders_integration();
|
809 |
+
}
|
810 |
+
|
811 |
+
/**
|
812 |
+
* Payment Gateway Integrations Initialized Action.
|
813 |
+
*
|
814 |
+
* Fired when integrations (Subscriptons/Pre-Orders) have been loaded and
|
815 |
+
* initialized.
|
816 |
+
*
|
817 |
+
* @since 3.0.0
|
818 |
+
*
|
819 |
+
* @param Payment_Gateway_Direct $this instance
|
820 |
+
*/
|
821 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_init_integrations', $this );
|
822 |
+
}
|
823 |
+
|
824 |
+
|
825 |
+
/**
|
826 |
+
* Gets an array of available integration objects
|
827 |
+
*
|
828 |
+
* @since 3.0.0
|
829 |
+
* @return array
|
830 |
+
*/
|
831 |
+
public function get_integrations() {
|
832 |
+
|
833 |
+
return $this->integrations;
|
834 |
+
}
|
835 |
+
|
836 |
+
|
837 |
+
/**
|
838 |
+
* Gets the integration object for the given ID.
|
839 |
+
*
|
840 |
+
* @since 3.0.0
|
841 |
+
*
|
842 |
+
* @param string $id the integration ID, e.g. subscriptions
|
843 |
+
* @return SquareFramework\PaymentGateway\Integrations\Payment_Gateway_Integration|null
|
844 |
+
*/
|
845 |
+
public function get_integration( $id ) {
|
846 |
+
|
847 |
+
return isset( $this->integrations[ $id ] ) ? $this->integrations[ $id ] : null;
|
848 |
+
}
|
849 |
+
|
850 |
+
|
851 |
+
/**
|
852 |
+
* Builds the Subscriptions integration class instance.
|
853 |
+
*
|
854 |
+
* Concrete classes can override this method to return a custom implementation.
|
855 |
+
*
|
856 |
+
* @since 3.0.0
|
857 |
+
*
|
858 |
+
* @return Payment_Gateway_Integration_Subscriptions
|
859 |
+
*/
|
860 |
+
protected function build_subscriptions_integration() {
|
861 |
+
|
862 |
+
return new Payment_Gateway_Integration_Subscriptions( $this );
|
863 |
+
}
|
864 |
+
|
865 |
+
|
866 |
+
/**
|
867 |
+
* Gets the Subscriptions integration class instance.
|
868 |
+
*
|
869 |
+
* @since 3.0.0
|
870 |
+
*
|
871 |
+
* @return Payment_Gateway_Integration_Subscriptions|null
|
872 |
+
*/
|
873 |
+
public function get_subscriptions_integration() {
|
874 |
+
|
875 |
+
return isset( $this->integrations[ self::INTEGRATION_SUBSCRIPTIONS ] ) ? $this->integrations[ self::INTEGRATION_SUBSCRIPTIONS ] : null;
|
876 |
+
}
|
877 |
+
|
878 |
+
|
879 |
+
/**
|
880 |
+
* Builds the Pre-Orders integration class instance.
|
881 |
+
*
|
882 |
+
* Concrete classes can override this method to return a custom implementation.
|
883 |
+
*
|
884 |
+
* @since 3.0.0
|
885 |
+
*
|
886 |
+
* @return Payment_Gateway_Integration_Pre_Orders
|
887 |
+
*/
|
888 |
+
protected function build_pre_orders_integration() {
|
889 |
+
|
890 |
+
return new Payment_Gateway_Integration_Pre_Orders( $this );
|
891 |
+
}
|
892 |
+
|
893 |
+
|
894 |
+
/**
|
895 |
+
* Gets the Pre-Orders integration class instance.
|
896 |
+
*
|
897 |
+
* @since 3.0.0
|
898 |
+
*
|
899 |
+
* @return Payment_Gateway_Integration_Pre_Orders|null
|
900 |
+
*/
|
901 |
+
public function get_pre_orders_integration() {
|
902 |
+
|
903 |
+
return isset( $this->integrations[ self::INTEGRATION_PRE_ORDERS ] ) ? $this->integrations[ self::INTEGRATION_PRE_ORDERS ] : null;
|
904 |
+
}
|
905 |
+
|
906 |
+
|
907 |
+
/**
|
908 |
+
* Determines if the gateway supports Subscriptions.
|
909 |
+
*
|
910 |
+
* A gateway supports Subscriptions if all of the following are true:
|
911 |
+
*
|
912 |
+
* + Subscriptions is active
|
913 |
+
* + tokenization is supported
|
914 |
+
* + tokenization is enabled
|
915 |
+
*
|
916 |
+
* Concrete gateways can override this to conditionally support Subscriptions
|
917 |
+
* based on certain settings (e.g. only when CSC is not required, etc.)
|
918 |
+
*
|
919 |
+
* @since 3.0.0
|
920 |
+
*
|
921 |
+
* @return bool
|
922 |
+
*/
|
923 |
+
public function supports_subscriptions() {
|
924 |
+
|
925 |
+
return $this->get_plugin()->is_subscriptions_active() && $this->supports_tokenization() && $this->tokenization_enabled();
|
926 |
+
}
|
927 |
+
|
928 |
+
|
929 |
+
/**
|
930 |
+
* Determines if the gateway supports Pre-Orders.
|
931 |
+
*
|
932 |
+
* A gateway supports Pre-Orders if all of the following are true:
|
933 |
+
*
|
934 |
+
* + Pre-Orders is active
|
935 |
+
* + tokenization is supported
|
936 |
+
* + tokenization is enabled
|
937 |
+
*
|
938 |
+
* Concrete gateways can override this to conditionally support Pre-Orders
|
939 |
+
* based on certain settings (e.g. only when CSC is not required, etc.)
|
940 |
+
*
|
941 |
+
* @since 3.0.0
|
942 |
+
*
|
943 |
+
* @return bool
|
944 |
+
*/
|
945 |
+
public function supports_pre_orders() {
|
946 |
+
|
947 |
+
return $this->get_plugin()->is_pre_orders_active() && $this->supports_tokenization() && $this->tokenization_enabled();
|
948 |
+
}
|
949 |
+
|
950 |
+
|
951 |
+
/** Apple Pay Feature *****************************************************/
|
952 |
+
|
953 |
+
|
954 |
+
/**
|
955 |
+
* Determines whether this gateway supports Apple Pay.
|
956 |
+
*
|
957 |
+
* @since 3.0.0
|
958 |
+
*
|
959 |
+
* @return bool
|
960 |
+
*/
|
961 |
+
public function supports_apple_pay() {
|
962 |
+
|
963 |
+
return $this->supports( self::FEATURE_APPLE_PAY );
|
964 |
+
}
|
965 |
+
|
966 |
+
|
967 |
+
/**
|
968 |
+
* Gets the Apple Pay gateway capabilities.
|
969 |
+
*
|
970 |
+
* Gateways should override this if they have more or less capabilities than
|
971 |
+
* the default. See https://developer.apple.com/reference/applepayjs/paymentrequest/1916123-merchantcapabilities
|
972 |
+
* for valid values.
|
973 |
+
*
|
974 |
+
* @since 3.0.0
|
975 |
+
*
|
976 |
+
* @return array
|
977 |
+
*/
|
978 |
+
public function get_apple_pay_capabilities() {
|
979 |
+
|
980 |
+
return array(
|
981 |
+
'supports3DS',
|
982 |
+
'supportsCredit',
|
983 |
+
'supportsDebit',
|
984 |
+
);
|
985 |
+
}
|
986 |
+
|
987 |
+
|
988 |
+
/**
|
989 |
+
* Gets the currencies supported by Apple Pay.
|
990 |
+
*
|
991 |
+
* @since 3.0.0
|
992 |
+
*
|
993 |
+
* @return array
|
994 |
+
*/
|
995 |
+
public function get_apple_pay_currencies() {
|
996 |
+
|
997 |
+
return array( 'USD' );
|
998 |
+
}
|
999 |
+
|
1000 |
+
|
1001 |
+
/**
|
1002 |
+
* Adds the Apple Pay payment data to the order object.
|
1003 |
+
*
|
1004 |
+
* Gateways should override this to set the appropriate values depending on
|
1005 |
+
* how their processing API needs to handle the data.
|
1006 |
+
*
|
1007 |
+
* @since 3.0.0
|
1008 |
+
*
|
1009 |
+
* @param \WC_Order the order object
|
1010 |
+
* @param Payment_Gateway_Apple_Pay_Payment_Response authorized payment response
|
1011 |
+
* @return \WC_Order
|
1012 |
+
*/
|
1013 |
+
public function get_order_for_apple_pay( \WC_Order $order, Payment_Gateway_Apple_Pay_Payment_Response $response ) {
|
1014 |
+
|
1015 |
+
$order->payment->account_number = $response->get_last_four();
|
1016 |
+
$order->payment->last_four = $response->get_last_four();
|
1017 |
+
$order->payment->card_type = $response->get_card_type();
|
1018 |
+
|
1019 |
+
return $order;
|
1020 |
+
}
|
1021 |
+
|
1022 |
+
|
1023 |
+
/**
|
1024 |
+
* Get the default payment method title, which is configurable within the
|
1025 |
+
* admin and displayed on checkout
|
1026 |
+
*
|
1027 |
+
* @since 3.0.0
|
1028 |
+
* @return string payment method title to show on checkout
|
1029 |
+
*/
|
1030 |
+
protected function get_default_title() {
|
1031 |
+
|
1032 |
+
// defaults for credit card, override for others
|
1033 |
+
if ( $this->is_credit_card_gateway() ) {
|
1034 |
+
return esc_html__( 'Credit Card', 'woocommerce-square' );
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
return '';
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
|
1041 |
+
/**
|
1042 |
+
* Get the default payment method description, which is configurable
|
1043 |
+
* within the admin and displayed on checkout
|
1044 |
+
*
|
1045 |
+
* @since 3.0.0
|
1046 |
+
* @return string payment method description to show on checkout
|
1047 |
+
*/
|
1048 |
+
protected function get_default_description() {
|
1049 |
+
|
1050 |
+
// defaults for credit card, override for others
|
1051 |
+
if ( $this->is_credit_card_gateway() ) {
|
1052 |
+
return esc_html__( 'Pay securely using your credit card.', 'woocommerce-square' );
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
return '';
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
|
1059 |
+
/**
|
1060 |
+
* Initialize payment gateway settings fields
|
1061 |
+
*
|
1062 |
+
* @since 3.0.0
|
1063 |
+
* @see WC_Settings_API::init_form_fields()
|
1064 |
+
*/
|
1065 |
+
public function init_form_fields() {
|
1066 |
+
|
1067 |
+
// common top form fields
|
1068 |
+
$this->form_fields = array(
|
1069 |
+
|
1070 |
+
'enabled' => array(
|
1071 |
+
'title' => esc_html__( 'Enable / Disable', 'woocommerce-square' ),
|
1072 |
+
'label' => esc_html__( 'Enable this gateway', 'woocommerce-square' ),
|
1073 |
+
'type' => 'checkbox',
|
1074 |
+
'default' => 'no',
|
1075 |
+
),
|
1076 |
+
|
1077 |
+
'title' => array(
|
1078 |
+
'title' => esc_html__( 'Title', 'woocommerce-square' ),
|
1079 |
+
'type' => 'text',
|
1080 |
+
'desc_tip' => esc_html__( 'Payment method title that the customer will see during checkout.', 'woocommerce-square' ),
|
1081 |
+
'default' => $this->get_default_title(),
|
1082 |
+
),
|
1083 |
+
|
1084 |
+
'description' => array(
|
1085 |
+
'title' => esc_html__( 'Description', 'woocommerce-square' ),
|
1086 |
+
'type' => 'textarea',
|
1087 |
+
'desc_tip' => esc_html__( 'Payment method description that the customer will see during checkout.', 'woocommerce-square' ),
|
1088 |
+
'default' => $this->get_default_description(),
|
1089 |
+
),
|
1090 |
+
|
1091 |
+
);
|
1092 |
+
|
1093 |
+
// Card Security Code (CVV) field
|
1094 |
+
if ( $this->is_credit_card_gateway() ) {
|
1095 |
+
$this->form_fields = $this->add_csc_form_fields( $this->form_fields );
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// both credit card authorization & charge supported
|
1099 |
+
if ( $this->supports_credit_card_authorization() && $this->supports_credit_card_charge() ) {
|
1100 |
+
$this->form_fields = $this->add_authorization_charge_form_fields( $this->form_fields );
|
1101 |
+
}
|
1102 |
+
|
1103 |
+
// card types support
|
1104 |
+
if ( $this->supports_card_types() ) {
|
1105 |
+
$this->form_fields = $this->add_card_types_form_fields( $this->form_fields );
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
// tokenization support
|
1109 |
+
if ( $this->supports_tokenization() ) {
|
1110 |
+
$this->form_fields = $this->add_tokenization_form_fields( $this->form_fields );
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
// add "detailed customer decline messages" option if the feature is supported
|
1114 |
+
if ( $this->supports( self::FEATURE_DETAILED_CUSTOMER_DECLINE_MESSAGES ) ) {
|
1115 |
+
$this->form_fields['enable_customer_decline_messages'] = array(
|
1116 |
+
'title' => esc_html__( 'Detailed Decline Messages', 'woocommerce-square' ),
|
1117 |
+
'type' => 'checkbox',
|
1118 |
+
'label' => esc_html__( 'Check to enable detailed decline messages to the customer during checkout when possible, rather than a generic decline message.', 'woocommerce-square' ),
|
1119 |
+
'default' => 'no',
|
1120 |
+
);
|
1121 |
+
}
|
1122 |
+
|
1123 |
+
// debug mode
|
1124 |
+
$this->form_fields['debug_mode'] = array(
|
1125 |
+
'title' => esc_html__( 'Debug Mode', 'woocommerce-square' ),
|
1126 |
+
'type' => 'select',
|
1127 |
+
/* translators: Placeholders: %1$s - <a> tag, %2$s - </a> tag */
|
1128 |
+
'desc' => sprintf( esc_html__( 'Show Detailed Error Messages and API requests/responses on the checkout page and/or save them to the %1$sdebug log%2$s', 'woocommerce-square' ), '<a href="' . Square_Helper::get_wc_log_file_url( $this->get_id() ) . '">', '</a>' ),
|
1129 |
+
'default' => self::DEBUG_MODE_OFF,
|
1130 |
+
'options' => array(
|
1131 |
+
self::DEBUG_MODE_OFF => esc_html__( 'Off', 'woocommerce-square' ),
|
1132 |
+
self::DEBUG_MODE_CHECKOUT => esc_html__( 'Show on Checkout Page', 'woocommerce-square' ),
|
1133 |
+
self::DEBUG_MODE_LOG => esc_html__( 'Save to Log', 'woocommerce-square' ),
|
1134 |
+
/* translators: show debugging information on both checkout page and in the log */
|
1135 |
+
self::DEBUG_MODE_BOTH => esc_html__( 'Both', 'woocommerce-square' )
|
1136 |
+
),
|
1137 |
+
);
|
1138 |
+
|
1139 |
+
// if there is more than just the production environment available
|
1140 |
+
if ( count( $this->get_environments() ) > 1 ) {
|
1141 |
+
$this->form_fields = $this->add_environment_form_fields( $this->form_fields );
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
// add the "inherit settings" toggle if there are settings shared with a sibling gateway
|
1145 |
+
if ( count( $this->shared_settings ) ) {
|
1146 |
+
$this->form_fields = $this->add_shared_settings_form_fields( $this->form_fields );
|
1147 |
+
}
|
1148 |
+
|
1149 |
+
// add unique method fields added by concrete gateway class
|
1150 |
+
$gateway_form_fields = $this->get_method_form_fields();
|
1151 |
+
$this->form_fields = array_merge( $this->form_fields, $gateway_form_fields );
|
1152 |
+
|
1153 |
+
// add the special 'shared-settings-field' class name to any shared settings fields
|
1154 |
+
foreach ( $this->shared_settings as $field_name ) {
|
1155 |
+
$this->form_fields[ $field_name ]['class'] = trim( isset( $this->form_fields[ $field_name ]['class'] ) ? $this->form_fields[ $field_name ]['class'] : '' ) . ' shared-settings-field';
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
/**
|
1159 |
+
* Payment Gateway Form Fields Filter.
|
1160 |
+
*
|
1161 |
+
* Actors can use this to add, remove, or tweak gateway form fields
|
1162 |
+
*
|
1163 |
+
* @since 3.0.0
|
1164 |
+
* @param array $form_fields array of form fields in format required by WC_Settings_API
|
1165 |
+
* @param Payment_Gateway $this gateway instance
|
1166 |
+
*/
|
1167 |
+
$this->form_fields = apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_form_fields', $this->form_fields, $this );
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
|
1171 |
+
/**
|
1172 |
+
* Returns an array of form fields specific for this method.
|
1173 |
+
*
|
1174 |
+
* To add environment-dependent fields, include the 'class' form field argument
|
1175 |
+
* with 'environment-field production-field' where "production" matches a
|
1176 |
+
* key from the environments member
|
1177 |
+
*
|
1178 |
+
* @since 3.0.0
|
1179 |
+
* @return array of form fields
|
1180 |
+
*/
|
1181 |
+
abstract protected function get_method_form_fields();
|
1182 |
+
|
1183 |
+
|
1184 |
+
/**
|
1185 |
+
* Adds the gateway environment form fields
|
1186 |
+
*
|
1187 |
+
* @since 3.0.0
|
1188 |
+
* @param array $form_fields gateway form fields
|
1189 |
+
* @return array $form_fields gateway form fields
|
1190 |
+
*/
|
1191 |
+
protected function add_environment_form_fields( $form_fields ) {
|
1192 |
+
|
1193 |
+
$form_fields['environment'] = array(
|
1194 |
+
/* translators: environment as in a software environment (test/production) */
|
1195 |
+
'title' => esc_html__( 'Environment', 'woocommerce-square' ),
|
1196 |
+
'type' => 'select',
|
1197 |
+
'default' => key( $this->get_environments() ), // default to first defined environment
|
1198 |
+
'desc_tip' => esc_html__( 'Select the gateway environment to use for transactions.', 'woocommerce-square' ),
|
1199 |
+
'options' => $this->get_environments(),
|
1200 |
+
);
|
1201 |
+
|
1202 |
+
return $form_fields;
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
|
1206 |
+
/**
|
1207 |
+
* Adds the optional shared settings toggle element. The 'shared_settings'
|
1208 |
+
* optional constructor parameter must have been used in order for shared
|
1209 |
+
* settings to be supported.
|
1210 |
+
*
|
1211 |
+
* @since 3.0.0
|
1212 |
+
* @see Payment_Gateway::$shared_settings
|
1213 |
+
* @see Payment_Gateway::$inherit_settings
|
1214 |
+
* @param array $form_fields gateway form fields
|
1215 |
+
* @return array $form_fields gateway form fields
|
1216 |
+
*/
|
1217 |
+
protected function add_shared_settings_form_fields( $form_fields ) {
|
1218 |
+
|
1219 |
+
// get any sibling gateways
|
1220 |
+
$other_gateway_ids = array_diff( $this->get_plugin()->get_gateway_ids(), array( $this->get_id() ) );
|
1221 |
+
$configured_other_gateway_ids = array();
|
1222 |
+
$inherit_settings_other_gateway_ids = array();
|
1223 |
+
|
1224 |
+
// determine if any sibling gateways have any configured shared settings
|
1225 |
+
foreach ( $other_gateway_ids as $other_gateway_id ) {
|
1226 |
+
|
1227 |
+
$other_gateway_settings = $this->get_plugin()->get_gateway_settings( $other_gateway_id );
|
1228 |
+
|
1229 |
+
// if the other gateway isn't also trying to inherit settings...
|
1230 |
+
if ( isset( $other_gateway_settings['inherit_settings'] ) && 'yes' == $other_gateway_settings['inherit_settings'] ) {
|
1231 |
+
$inherit_settings_other_gateway_ids[] = $other_gateway_id;
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
foreach ( $this->shared_settings as $setting_name ) {
|
1235 |
+
|
1236 |
+
// if at least one shared setting is configured in the other gateway
|
1237 |
+
if ( isset( $other_gateway_settings[ $setting_name ] ) && $other_gateway_settings[ $setting_name ] ) {
|
1238 |
+
|
1239 |
+
$configured_other_gateway_ids[] = $other_gateway_id;
|
1240 |
+
break;
|
1241 |
+
}
|
1242 |
+
}
|
1243 |
+
}
|
1244 |
+
|
1245 |
+
$form_fields['connection_settings'] = array(
|
1246 |
+
'title' => esc_html__( 'Connection Settings', 'woocommerce-square' ),
|
1247 |
+
'type' => 'title',
|
1248 |
+
);
|
1249 |
+
|
1250 |
+
// disable the field if the sibling gateway is already inheriting settings
|
1251 |
+
$form_fields['inherit_settings'] = array(
|
1252 |
+
'title' => esc_html__( 'Share connection settings', 'woocommerce-square' ),
|
1253 |
+
'type' => 'checkbox',
|
1254 |
+
'label' => esc_html__( 'Use connection/authentication settings from other gateway', 'woocommerce-square' ),
|
1255 |
+
'default' => count( $configured_other_gateway_ids ) > 0 ? 'yes' : 'no',
|
1256 |
+
'disabled' => count( $inherit_settings_other_gateway_ids ) > 0 ? true : false,
|
1257 |
+
'description' => count( $inherit_settings_other_gateway_ids ) > 0 ? esc_html__( 'Disabled because the other gateway is using these settings', 'woocommerce-square' ) : '',
|
1258 |
+
);
|
1259 |
+
|
1260 |
+
return $form_fields;
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
|
1264 |
+
/**
|
1265 |
+
* Adds the enable Card Security Code form fields
|
1266 |
+
*
|
1267 |
+
* @since 3.0.0
|
1268 |
+
* @param array $form_fields gateway form fields
|
1269 |
+
* @return array $form_fields gateway form fields
|
1270 |
+
*/
|
1271 |
+
protected function add_csc_form_fields( $form_fields ) {
|
1272 |
+
|
1273 |
+
$form_fields['enable_csc'] = array(
|
1274 |
+
'title' => esc_html__( 'Card Verification (CSC)', 'woocommerce-square' ),
|
1275 |
+
'label' => esc_html__( 'Display the Card Security Code (CV2) field on checkout', 'woocommerce-square' ),
|
1276 |
+
'type' => 'checkbox',
|
1277 |
+
'default' => 'yes',
|
1278 |
+
);
|
1279 |
+
|
1280 |
+
if ( $this->supports_tokenization() ) {
|
1281 |
+
|
1282 |
+
$form_fields['enable_token_csc'] = array(
|
1283 |
+
'title' => esc_html__( 'Saved Card Verification', 'woocommerce-square' ),
|
1284 |
+
'label' => esc_html__( 'Display the Card Security Code field when paying with a saved card', 'woocommerce-square' ),
|
1285 |
+
'type' => 'checkbox',
|
1286 |
+
'default' => 'yes',
|
1287 |
+
);
|
1288 |
+
}
|
1289 |
+
|
1290 |
+
return $form_fields;
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
|
1294 |
+
/**
|
1295 |
+
* Displays settings page with some additional javascript for hiding conditional fields.
|
1296 |
+
*
|
1297 |
+
* @see \WC_Settings_API::admin_options()
|
1298 |
+
*
|
1299 |
+
* @since 3.0.0
|
1300 |
+
*/
|
1301 |
+
public function admin_options() {
|
1302 |
+
|
1303 |
+
parent::admin_options();
|
1304 |
+
|
1305 |
+
?>
|
1306 |
+
<style type="text/css">.nowrap { white-space: nowrap; }</style>
|
1307 |
+
<?php
|
1308 |
+
|
1309 |
+
if ( isset( $this->form_fields['enable_csc'] ) ) {
|
1310 |
+
|
1311 |
+
// add inline javascript to show/hide any shared settings fields as needed
|
1312 |
+
ob_start();
|
1313 |
+
?>
|
1314 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_enable_csc' ).change( function() {
|
1315 |
+
|
1316 |
+
var enabled = $( this ).is( ':checked' );
|
1317 |
+
|
1318 |
+
if ( enabled ) {
|
1319 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_enable_token_csc' ).closest( 'tr' ).show();
|
1320 |
+
} else {
|
1321 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_enable_token_csc' ).closest( 'tr' ).hide();
|
1322 |
+
}
|
1323 |
+
|
1324 |
+
} ).change();
|
1325 |
+
<?php
|
1326 |
+
|
1327 |
+
wc_enqueue_js( ob_get_clean() );
|
1328 |
+
|
1329 |
+
}
|
1330 |
+
|
1331 |
+
// if transaction types are supported, show/hide the "charge virtual-only" setting
|
1332 |
+
if ( isset( $this->form_fields['transaction_type'] ) ) {
|
1333 |
+
|
1334 |
+
// add inline javascript
|
1335 |
+
ob_start();
|
1336 |
+
?>
|
1337 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_transaction_type' ).change( function() {
|
1338 |
+
|
1339 |
+
var transaction_type = $( this ).val();
|
1340 |
+
var hidden_settings = $( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_charge_virtual_orders, #woocommerce_<?php echo esc_js( $this->get_id() ); ?>_enable_partial_capture, #woocommerce_<?php echo esc_js( $this->get_id() ); ?>_enable_paid_capture' ).closest( 'tr' );
|
1341 |
+
|
1342 |
+
if ( '<?php echo esc_js( self::TRANSACTION_TYPE_AUTHORIZATION ); ?>' === transaction_type ) {
|
1343 |
+
$( hidden_settings ).show();
|
1344 |
+
} else {
|
1345 |
+
$( hidden_settings ).hide();
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
} ).change();
|
1349 |
+
<?php
|
1350 |
+
|
1351 |
+
wc_enqueue_js( ob_get_clean() );
|
1352 |
+
}
|
1353 |
+
|
1354 |
+
// if there's more than one environment include the environment settings switcher code
|
1355 |
+
if ( count( $this->get_environments() ) > 1 ) {
|
1356 |
+
|
1357 |
+
// add inline javascript
|
1358 |
+
ob_start();
|
1359 |
+
?>
|
1360 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_environment' ).change( function() {
|
1361 |
+
|
1362 |
+
// inherit settings from other gateway?
|
1363 |
+
var inheritSettings = $( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_inherit_settings' ).is( ':checked' );
|
1364 |
+
|
1365 |
+
var environment = $( this ).val();
|
1366 |
+
|
1367 |
+
// hide all environment-dependant fields
|
1368 |
+
$( '.environment-field' ).closest( 'tr' ).hide();
|
1369 |
+
|
1370 |
+
// show the currently configured environment fields that are not also being hidden as any shared settings
|
1371 |
+
var $environmentFields = $( '.' + environment + '-field' );
|
1372 |
+
if ( inheritSettings ) {
|
1373 |
+
$environmentFields = $environmentFields.not( '.shared-settings-field' );
|
1374 |
+
}
|
1375 |
+
|
1376 |
+
$environmentFields.not( '.hidden' ).closest( 'tr' ).show();
|
1377 |
+
|
1378 |
+
} ).change();
|
1379 |
+
<?php
|
1380 |
+
|
1381 |
+
wc_enqueue_js( ob_get_clean() );
|
1382 |
+
|
1383 |
+
}
|
1384 |
+
|
1385 |
+
if ( ! empty( $this->shared_settings ) ) {
|
1386 |
+
|
1387 |
+
// add inline javascript to show/hide any shared settings fields as needed
|
1388 |
+
ob_start();
|
1389 |
+
?>
|
1390 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_inherit_settings' ).change( function() {
|
1391 |
+
|
1392 |
+
var enabled = $( this ).is( ':checked' );
|
1393 |
+
|
1394 |
+
if ( enabled ) {
|
1395 |
+
$( '.shared-settings-field' ).closest( 'tr' ).hide();
|
1396 |
+
} else {
|
1397 |
+
// show the fields
|
1398 |
+
$( '.shared-settings-field' ).closest( 'tr' ).show();
|
1399 |
+
|
1400 |
+
// hide any that may not be available for the currently selected environment
|
1401 |
+
$( '#woocommerce_<?php echo esc_js( $this->get_id() ); ?>_environment' ).change();
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
} ).change();
|
1405 |
+
<?php
|
1406 |
+
|
1407 |
+
wc_enqueue_js( ob_get_clean() );
|
1408 |
+
|
1409 |
+
}
|
1410 |
+
|
1411 |
+
}
|
1412 |
+
|
1413 |
+
|
1414 |
+
/**
|
1415 |
+
* Checks for proper gateway configuration including:
|
1416 |
+
*
|
1417 |
+
* + gateway enabled
|
1418 |
+
* + correct configuration (gateway specific)
|
1419 |
+
* + any dependencies met
|
1420 |
+
* + required currency
|
1421 |
+
* + required country
|
1422 |
+
*
|
1423 |
+
* @since 3.0.0
|
1424 |
+
* @see WC_Payment_Gateway::is_available()
|
1425 |
+
* @return true if this gateway is available for checkout, false otherwise
|
1426 |
+
*/
|
1427 |
+
public function is_available() {
|
1428 |
+
|
1429 |
+
// is enabled check
|
1430 |
+
$is_available = parent::is_available();
|
1431 |
+
|
1432 |
+
// proper configuration
|
1433 |
+
if ( ! $this->is_configured() ) {
|
1434 |
+
$is_available = false;
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
// all plugin dependencies met
|
1438 |
+
if ( count( $this->get_plugin()->get_dependency_handler()->get_missing_php_extensions() ) > 0 ) {
|
1439 |
+
$is_available = false;
|
1440 |
+
}
|
1441 |
+
|
1442 |
+
// any required currencies?
|
1443 |
+
if ( ! $this->currency_is_accepted() ) {
|
1444 |
+
$is_available = false;
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
// any required countries?
|
1448 |
+
if ( $this->countries && WC()->customer ) {
|
1449 |
+
|
1450 |
+
$customer_country = WC()->customer->get_billing_country();
|
1451 |
+
|
1452 |
+
if ( $customer_country && ! in_array( $customer_country, $this->countries, true ) ) {
|
1453 |
+
$is_available = false;
|
1454 |
+
}
|
1455 |
+
}
|
1456 |
+
|
1457 |
+
/**
|
1458 |
+
* Payment Gateway Is Available Filter.
|
1459 |
+
*
|
1460 |
+
* Allow actors to modify whether the gateway is available or not.
|
1461 |
+
*
|
1462 |
+
* @since 3.0.0
|
1463 |
+
* @param bool $is_available
|
1464 |
+
*/
|
1465 |
+
return apply_filters( 'wc_gateway_' . $this->get_id() . '_is_available', $is_available );
|
1466 |
+
}
|
1467 |
+
|
1468 |
+
|
1469 |
+
/**
|
1470 |
+
* Returns true if the gateway is properly configured to perform transactions
|
1471 |
+
*
|
1472 |
+
* @since 3.0.0
|
1473 |
+
* @see Payment_Gateway::is_configured()
|
1474 |
+
* @return boolean true if the gateway is properly configured
|
1475 |
+
*/
|
1476 |
+
protected function is_configured() {
|
1477 |
+
// override this to check for gateway-specific required settings (user names, passwords, secret keys, etc)
|
1478 |
+
return true;
|
1479 |
+
}
|
1480 |
+
|
1481 |
+
/**
|
1482 |
+
* Returns the payment method image URL (if any) for the given $type, ie
|
1483 |
+
* if $type is 'amex' a URL to the american express card icon will be
|
1484 |
+
* returned.
|
1485 |
+
*
|
1486 |
+
* @since 3.0.0
|
1487 |
+
* @param string $type the payment method cc type or name
|
1488 |
+
* @return string the image URL or null
|
1489 |
+
*/
|
1490 |
+
public function get_payment_method_image_url( $type ) {
|
1491 |
+
|
1492 |
+
$image_type = strtolower( $type );
|
1493 |
+
|
1494 |
+
if ( 'card' === $type ) {
|
1495 |
+
$image_type = 'cc-plain';
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
/**
|
1499 |
+
* Payment Gateway Fallback to PNG Filter.
|
1500 |
+
*
|
1501 |
+
* Allow actors to enable the use of PNGs over SVGs for payment icon images.
|
1502 |
+
*
|
1503 |
+
* @since 3.0.0
|
1504 |
+
* @param bool $use_svg true by default, false to use PNGs
|
1505 |
+
*/
|
1506 |
+
$image_extension = apply_filters( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_use_svg', true ) ? '.svg' : '.png';
|
1507 |
+
|
1508 |
+
// first, is the card image available within the plugin?
|
1509 |
+
if ( is_readable( $this->get_plugin()->get_payment_gateway_framework_assets_path() . '/images/card-' . $image_type . $image_extension ) ) {
|
1510 |
+
return \WC_HTTPS::force_https_url( $this->get_plugin()->get_payment_gateway_framework_assets_url() . '/images/card-' . $image_type . $image_extension );
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
// default: is the card image available within the framework?
|
1514 |
+
if ( is_readable( $this->get_plugin()->get_payment_gateway_framework_assets_path() . '/images/card-' . $image_type . $image_extension ) ) {
|
1515 |
+
return \WC_HTTPS::force_https_url( $this->get_plugin()->get_payment_gateway_framework_assets_url() . '/images/card-' . $image_type . $image_extension );
|
1516 |
+
}
|
1517 |
+
|
1518 |
+
return null;
|
1519 |
+
}
|
1520 |
+
|
1521 |
+
|
1522 |
+
/**
|
1523 |
+
* Add payment and transaction information as class members of WC_Order
|
1524 |
+
* instance. The standard information that can be added includes:
|
1525 |
+
*
|
1526 |
+
* $order->payment_total - the payment total
|
1527 |
+
* $order->customer_id - optional payment gateway customer id (useful for tokenized payments, etc)
|
1528 |
+
* $order->payment->type - one of 'credit_card' or 'check'
|
1529 |
+
* $order->description - an order description based on the order
|
1530 |
+
* $order->unique_transaction_ref - a combination of order number + retry count, should provide a unique value for each transaction attempt
|
1531 |
+
*
|
1532 |
+
* Note that not all gateways will necessarily pass or require all of the
|
1533 |
+
* above. These represent the most common attributes used among a variety
|
1534 |
+
* of gateways, it's up to the specific gateway implementation to make use
|
1535 |
+
* of, or ignore them, or add custom ones by overridding this method.
|
1536 |
+
*
|
1537 |
+
* The returned order is expected to be used in a transaction request.
|
1538 |
+
*
|
1539 |
+
* @since 3.0.0
|
1540 |
+
* @param int|\WC_Order $order the order or order ID being processed
|
1541 |
+
* @return \WC_Order object with payment and transaction information attached
|
1542 |
+
*/
|
1543 |
+
public function get_order( $order ) {
|
1544 |
+
|
1545 |
+
if ( is_numeric( $order ) ) {
|
1546 |
+
$order = wc_get_order( $order );
|
1547 |
+
}
|
1548 |
+
|
1549 |
+
// set payment total here so it can be modified for later by add-ons like subscriptions which may need to charge an amount different than the get_total()
|
1550 |
+
$order->payment_total = number_format( $order->get_total(), 2, '.', '' );
|
1551 |
+
|
1552 |
+
$order->customer_id = '';
|
1553 |
+
|
1554 |
+
// logged in customer?
|
1555 |
+
if ( 0 != $order->get_user_id() && false !== ( $customer_id = $this->get_customer_id( $order->get_user_id(), array( 'order' => $order ) ) ) ) {
|
1556 |
+
$order->customer_id = $customer_id;
|
1557 |
+
}
|
1558 |
+
|
1559 |
+
// add payment info
|
1560 |
+
$order->payment = new \stdClass();
|
1561 |
+
|
1562 |
+
// payment type (credit_card/check/etc)
|
1563 |
+
$order->payment->type = str_replace( '-', '_', $this->get_payment_type() );
|
1564 |
+
|
1565 |
+
/* translators: Placeholders: %1$s - site title, %2$s - order number */
|
1566 |
+
$order->description = sprintf( esc_html__( '%1$s - Order %2$s', 'woocommerce-square' ), wp_specialchars_decode( Square_Helper::get_site_name(), ENT_QUOTES ), $order->get_order_number() );
|
1567 |
+
|
1568 |
+
$order = $this->get_order_with_unique_transaction_ref( $order );
|
1569 |
+
|
1570 |
+
/**
|
1571 |
+
* Filters the base order for a payment transaction.
|
1572 |
+
*
|
1573 |
+
* Actors can use this filter to adjust or add additional information to
|
1574 |
+
* the order object that gateways use for processing transactions.
|
1575 |
+
*
|
1576 |
+
* @since 3.0.0
|
1577 |
+
*
|
1578 |
+
* @param \WC_Order $order order object
|
1579 |
+
* @param Payment_Gateway $this payment gateway instance
|
1580 |
+
*/
|
1581 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_get_order_base', $order, $this );
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
|
1585 |
+
/**
|
1586 |
+
* Completes an order payment.
|
1587 |
+
*
|
1588 |
+
* This method marks the order with an appropriate status, and adds a relevant order note.
|
1589 |
+
*
|
1590 |
+
* @since 3.0.0
|
1591 |
+
*
|
1592 |
+
* @param \WC_Order $order order object
|
1593 |
+
* @param Payment_Gateway_API_Response $response response object
|
1594 |
+
* @throws \Exception
|
1595 |
+
*/
|
1596 |
+
protected function complete_payment( \WC_Order $order, Payment_Gateway_API_Response $response ) {
|
1597 |
+
|
1598 |
+
if ( self::PAYMENT_TYPE_CREDIT_CARD == $response->get_payment_type() ) {
|
1599 |
+
$order->add_order_note( $this->get_credit_card_transaction_approved_message( $order, $response ) );
|
1600 |
+
} else {
|
1601 |
+
$message_method = 'get_' . $response->get_payment_type() . '_transaction_approved_message';
|
1602 |
+
|
1603 |
+
if ( is_callable( array( $this, $message_method ) ) ) {
|
1604 |
+
$order->add_order_note( $this->$message_method( $order, $response ) );
|
1605 |
+
}
|
1606 |
+
}
|
1607 |
+
|
1608 |
+
if ( $response->transaction_held() || ( $this->supports_credit_card_authorization() && $this->perform_credit_card_authorization( $order ) ) ) {
|
1609 |
+
|
1610 |
+
$message = $this->supports_credit_card_authorization() && $this->perform_credit_card_authorization( $order ) ? __( 'Authorization only transaction', 'woocommerce-square' ) : $response->get_status_message();
|
1611 |
+
|
1612 |
+
$this->mark_order_as_held( $order, $message, $response );
|
1613 |
+
|
1614 |
+
wc_reduce_stock_levels( $order->get_id() );
|
1615 |
+
|
1616 |
+
} else {
|
1617 |
+
|
1618 |
+
$order->payment_complete();
|
1619 |
+
}
|
1620 |
+
|
1621 |
+
/**
|
1622 |
+
* Fires after a payment transaction is successfully completed.
|
1623 |
+
*
|
1624 |
+
* @since 3.0.0
|
1625 |
+
*
|
1626 |
+
* @param \WC_Order $order order object
|
1627 |
+
* @param Payment_Gateway $gateway gateway object
|
1628 |
+
*/
|
1629 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_complete_payment', $order, $this );
|
1630 |
+
}
|
1631 |
+
|
1632 |
+
|
1633 |
+
/** Capture Methods ***********************************************************************************************/
|
1634 |
+
|
1635 |
+
|
1636 |
+
/**
|
1637 |
+
* Builds the capture handler instance.
|
1638 |
+
*
|
1639 |
+
* @since 3.0.0
|
1640 |
+
*/
|
1641 |
+
public function init_capture_handler() {
|
1642 |
+
|
1643 |
+
$this->capture_handler = new Capture( $this );
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
|
1647 |
+
/**
|
1648 |
+
* Gets the capture handler instance.
|
1649 |
+
*
|
1650 |
+
* @since 3.0.0
|
1651 |
+
*
|
1652 |
+
* @return Payment_Gateway\Handlers\Capture
|
1653 |
+
*/
|
1654 |
+
public function get_capture_handler() {
|
1655 |
+
|
1656 |
+
return $this->capture_handler;
|
1657 |
+
}
|
1658 |
+
|
1659 |
+
|
1660 |
+
/**
|
1661 |
+
* Gets an order object with payment data added for use in credit card capture transactions.
|
1662 |
+
*
|
1663 |
+
* This was intentionally not moved to the capture handler since we'll likely be refactoring how this information is
|
1664 |
+
* set in the future, and plenty of gateways override it.
|
1665 |
+
*
|
1666 |
+
* @since 3.0.0
|
1667 |
+
*
|
1668 |
+
* @param \WC_Order|int $order the order being processed
|
1669 |
+
* @param float|null $amount amount to capture or null for the full order amount
|
1670 |
+
* @return \WC_Order
|
1671 |
+
*/
|
1672 |
+
public function get_order_for_capture( $order, $amount = null ) {
|
1673 |
+
|
1674 |
+
if ( is_numeric( $order ) ) {
|
1675 |
+
$order = wc_get_order( $order );
|
1676 |
+
}
|
1677 |
+
|
1678 |
+
// add capture info
|
1679 |
+
$order->capture = new \stdClass();
|
1680 |
+
|
1681 |
+
$total_captured = $this->get_order_meta( $order, 'capture_total' );
|
1682 |
+
|
1683 |
+
// if no amount is specified, as in a bulk capture situation, always use the amount remaining
|
1684 |
+
if ( ! $amount ) {
|
1685 |
+
$amount = (float) $order->get_total() - (float) $total_captured;
|
1686 |
+
}
|
1687 |
+
|
1688 |
+
$order->capture->amount = Square_Helper::number_format( $amount );
|
1689 |
+
|
1690 |
+
/* translators: Placeholders: %1$s - site title, %2$s - order number. Definitions: Capture as in capture funds from a credit card. */
|
1691 |
+
$order->capture->description = sprintf( esc_html__( '%1$s - Capture for Order %2$s', 'woocommerce-square' ), wp_specialchars_decode( Square_Helper::get_site_name() ), $order->get_order_number() );
|
1692 |
+
$order->capture->trans_id = $this->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'trans_id' );
|
1693 |
+
|
1694 |
+
/**
|
1695 |
+
* Direct Gateway Capture Get Order Filter.
|
1696 |
+
*
|
1697 |
+
* Allow actors to modify the order object used for performing charge captures.
|
1698 |
+
*
|
1699 |
+
* @since 3.0.0
|
1700 |
+
* @param \WC_Order $order order object
|
1701 |
+
* @param Payment_Gateway $this instance
|
1702 |
+
*/
|
1703 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_get_order_for_capture', $order, $this );
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
/**
|
1707 |
+
* Processes a refund.
|
1708 |
+
*
|
1709 |
+
* @since 3.0.0
|
1710 |
+
*
|
1711 |
+
* @param int $order_id order being refunded
|
1712 |
+
* @param float $amount refund amount
|
1713 |
+
* @param string $reason user-entered reason text for refund
|
1714 |
+
* @return bool|\WP_Error true on success, or a WP_Error object on failure/error
|
1715 |
+
*/
|
1716 |
+
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
1717 |
+
|
1718 |
+
// add transaction-specific refund info (amount, reason, transaction IDs, etc)
|
1719 |
+
$order = $this->get_order_for_refund( $order_id, $amount, $reason );
|
1720 |
+
|
1721 |
+
// let implementations/actors error out early (e.g. order is missing required data for refund, etc)
|
1722 |
+
if ( is_wp_error( $order ) ) {
|
1723 |
+
return $order;
|
1724 |
+
}
|
1725 |
+
|
1726 |
+
// if captures are supported and the order has an authorized, but not captured charge, void it instead
|
1727 |
+
if ( $this->supports_voids() && ! $this->get_capture_handler()->is_order_captured( $order ) ) {
|
1728 |
+
return $this->process_void( $order );
|
1729 |
+
}
|
1730 |
+
|
1731 |
+
try {
|
1732 |
+
|
1733 |
+
$response = $response = $this->get_api()->refund( $order );
|
1734 |
+
|
1735 |
+
// allow gateways to void an order in response to a refund attempt
|
1736 |
+
if ( $this->supports_voids() && $this->maybe_void_instead_of_refund( $order, $response ) ) {
|
1737 |
+
return $this->process_void( $order );
|
1738 |
+
}
|
1739 |
+
|
1740 |
+
if ( $response->transaction_approved() ) {
|
1741 |
+
|
1742 |
+
// add standard refund-specific transaction data
|
1743 |
+
$this->add_refund_data( $order, $response );
|
1744 |
+
|
1745 |
+
// add order note
|
1746 |
+
$this->add_refund_order_note( $order, $response );
|
1747 |
+
|
1748 |
+
// when full amount is refunded, update status to refunded
|
1749 |
+
if ( $order->get_total() == $order->get_total_refunded() ) {
|
1750 |
+
$this->mark_order_as_refunded( $order );
|
1751 |
+
}
|
1752 |
+
|
1753 |
+
/**
|
1754 |
+
* Fires after a refund is successfully processed.
|
1755 |
+
*
|
1756 |
+
* @since 3.0.0
|
1757 |
+
*
|
1758 |
+
* @param \WC_Order $order order object
|
1759 |
+
* @param Payment_Gateway $gateway payment gateway instance
|
1760 |
+
*/
|
1761 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_refund_processed', $order, $this );
|
1762 |
+
|
1763 |
+
return true;
|
1764 |
+
|
1765 |
+
} else {
|
1766 |
+
|
1767 |
+
$error = $this->get_refund_failed_wp_error( $response->get_status_code(), $response->get_status_message() );
|
1768 |
+
|
1769 |
+
$order->add_order_note( $error->get_error_message() );
|
1770 |
+
|
1771 |
+
return $error;
|
1772 |
+
}
|
1773 |
+
|
1774 |
+
} catch ( \Exception $e ) {
|
1775 |
+
|
1776 |
+
$error = $this->get_refund_failed_wp_error( $e->getCode(), $e->getMessage() );
|
1777 |
+
|
1778 |
+
$order->add_order_note( $error->get_error_message() );
|
1779 |
+
|
1780 |
+
return $error;
|
1781 |
+
}
|
1782 |
+
}
|
1783 |
+
|
1784 |
+
/**
|
1785 |
+
* Add refund information as class members of WC_Order
|
1786 |
+
* instance for use in refund transactions. Standard information includes:
|
1787 |
+
*
|
1788 |
+
* $order->refund->amount = refund amount
|
1789 |
+
* $order->refund->reason = user-entered reason text for the refund
|
1790 |
+
* $order->refund->trans_id = the ID of the original payment transaction for the order
|
1791 |
+
*
|
1792 |
+
* Payment gateway implementations can override this to add their own
|
1793 |
+
* refund-specific data
|
1794 |
+
*
|
1795 |
+
* @since 3.0.0
|
1796 |
+
*
|
1797 |
+
* @param \WC_Order|int $order order being processed
|
1798 |
+
* @param float $amount refund amount
|
1799 |
+
* @param string $reason optional refund reason text
|
1800 |
+
* @return \WC_Order|\WP_Error object with refund information attached
|
1801 |
+
*/
|
1802 |
+
protected function get_order_for_refund( $order, $amount, $reason ) {
|
1803 |
+
|
1804 |
+
if ( is_numeric( $order ) ) {
|
1805 |
+
$order = wc_get_order( $order );
|
1806 |
+
}
|
1807 |
+
|
1808 |
+
// add refund info
|
1809 |
+
$order->refund = new \stdClass();
|
1810 |
+
$order->refund->amount = number_format( $amount, 2, '.', '' );
|
1811 |
+
|
1812 |
+
/* translators: Placeholders: %1$s - site title, %2$s - order number */
|
1813 |
+
$order->refund->reason = $reason ? $reason : sprintf( esc_html__( '%1$s - Refund for Order %2$s', 'woocommerce-square' ), esc_html( Square_Helper::get_site_name() ), $order->get_order_number() );
|
1814 |
+
|
1815 |
+
// almost all gateways require the original transaction ID, so include it by default
|
1816 |
+
$order->refund->trans_id = $this->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'trans_id' );
|
1817 |
+
|
1818 |
+
/**
|
1819 |
+
* Payment Gateway Get Order For Refund Filter.
|
1820 |
+
*
|
1821 |
+
* Allow actors to modify the order object used for refund transactions.
|
1822 |
+
*
|
1823 |
+
* @since 3.0.0
|
1824 |
+
*
|
1825 |
+
* @param \WC_Order|\WP_Error $order order object
|
1826 |
+
* @param Payment_Gateway $this instance
|
1827 |
+
*/
|
1828 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_get_order_for_refund', $order, $this );
|
1829 |
+
}
|
1830 |
+
|
1831 |
+
|
1832 |
+
/**
|
1833 |
+
* Adds the standard refund transaction data to the order.
|
1834 |
+
*
|
1835 |
+
* Note that refunds can be performed multiple times for a single order so
|
1836 |
+
* transaction IDs keys are not unique
|
1837 |
+
*
|
1838 |
+
* @since 3.0.0
|
1839 |
+
*
|
1840 |
+
* @param \WC_Order $order the order object
|
1841 |
+
* @param Payment_Gateway_API_Response $response transaction response
|
1842 |
+
*/
|
1843 |
+
protected function add_refund_data( \WC_Order $order, $response ) {
|
1844 |
+
|
1845 |
+
// indicate the order was refunded along with the refund amount
|
1846 |
+
$this->add_order_meta( $order, 'refund_amount', $order->refund->amount );
|
1847 |
+
|
1848 |
+
// add refund transaction ID
|
1849 |
+
if ( $response && $response->get_transaction_id() ) {
|
1850 |
+
$this->add_order_meta( $order, 'refund_trans_id', $response->get_transaction_id() );
|
1851 |
+
}
|
1852 |
+
}
|
1853 |
+
|
1854 |
+
/**
|
1855 |
+
* Adds an order note with the amount and (optional) refund transaction ID.
|
1856 |
+
*
|
1857 |
+
* @since 3.0.0
|
1858 |
+
*
|
1859 |
+
* @param \WC_Order $order order object
|
1860 |
+
* @param Payment_Gateway_API_Response $response transaction response
|
1861 |
+
*/
|
1862 |
+
protected function add_refund_order_note( \WC_Order $order, $response ) {
|
1863 |
+
|
1864 |
+
$message = sprintf(
|
1865 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - a monetary amount */
|
1866 |
+
esc_html__( '%1$s Refund in the amount of %2$s approved.', 'woocommerce-square' ),
|
1867 |
+
$this->get_method_title(),
|
1868 |
+
wc_price( $order->refund->amount, array( 'currency' => Order_Compatibility::get_prop( $order, 'currency', 'view' ) ) )
|
1869 |
+
);
|
1870 |
+
|
1871 |
+
// adds the transaction id (if any) to the order note
|
1872 |
+
if ( $response->get_transaction_id() ) {
|
1873 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
1874 |
+
}
|
1875 |
+
|
1876 |
+
$order->add_order_note( $message );
|
1877 |
+
}
|
1878 |
+
|
1879 |
+
|
1880 |
+
/**
|
1881 |
+
* Builds the WP_Error object for a failed refund.
|
1882 |
+
*
|
1883 |
+
* @since 3.0.0
|
1884 |
+
*
|
1885 |
+
* @param int|string $error_code error code
|
1886 |
+
* @param string $error_message error message
|
1887 |
+
* @return \WP_Error suitable for returning from the process_refund() method
|
1888 |
+
*/
|
1889 |
+
protected function get_refund_failed_wp_error( $error_code, $error_message ) {
|
1890 |
+
|
1891 |
+
if ( $error_code ) {
|
1892 |
+
$message = sprintf(
|
1893 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - error code, %3$s - error message */
|
1894 |
+
esc_html__( '%1$s Refund Failed: %2$s - %3$s', 'woocommerce-square' ),
|
1895 |
+
$this->get_method_title(),
|
1896 |
+
$error_code,
|
1897 |
+
$error_message
|
1898 |
+
);
|
1899 |
+
} else {
|
1900 |
+
$message = sprintf(
|
1901 |
+
/* translators: Placeholders: %1$s - payment gateway title (such as Authorize.net, Braintree, etc), %2$s - error message */
|
1902 |
+
esc_html__( '%1$s Refund Failed: %2$s', 'woocommerce-square' ),
|
1903 |
+
$this->get_method_title(),
|
1904 |
+
$error_message
|
1905 |
+
);
|
1906 |
+
}
|
1907 |
+
|
1908 |
+
return new \WP_Error( 'wc_' . $this->get_id() . '_refund_failed', $message );
|
1909 |
+
}
|
1910 |
+
|
1911 |
+
|
1912 |
+
/**
|
1913 |
+
* Mark an order as refunded. This should only be used when the full order
|
1914 |
+
* amount has been refunded.
|
1915 |
+
*
|
1916 |
+
* @since 3.0.0
|
1917 |
+
*
|
1918 |
+
* @param \WC_Order $order order object
|
1919 |
+
*/
|
1920 |
+
public function mark_order_as_refunded( $order ) {
|
1921 |
+
|
1922 |
+
/* translators: Placeholders: %s - payment gateway title (such as Authorize.net, Braintree, etc) */
|
1923 |
+
$order_note = sprintf( esc_html__( '%s Order completely refunded.', 'woocommerce-square' ), $this->get_method_title() );
|
1924 |
+
|
1925 |
+
// Mark order as refunded if not already set
|
1926 |
+
if ( ! $order->has_status( 'refunded' ) ) {
|
1927 |
+
$order->update_status( 'refunded', $order_note );
|
1928 |
+
} else {
|
1929 |
+
$order->add_order_note( $order_note );
|
1930 |
+
}
|
1931 |
+
}
|
1932 |
+
|
1933 |
+
|
1934 |
+
/** Void feature ********************************************************/
|
1935 |
+
|
1936 |
+
|
1937 |
+
/**
|
1938 |
+
* Returns true if this is gateway that supports voids
|
1939 |
+
*
|
1940 |
+
* @since 3.0.0
|
1941 |
+
* @return boolean true if the gateway supports voids
|
1942 |
+
*/
|
1943 |
+
public function supports_voids() {
|
1944 |
+
|
1945 |
+
return $this->supports( self::FEATURE_VOIDS ) && $this->supports_credit_card_capture();
|
1946 |
+
}
|
1947 |
+
|
1948 |
+
|
1949 |
+
/**
|
1950 |
+
* Allow gateways to void an order that was attempted to be refunded. This is
|
1951 |
+
* particularly useful for gateways that can void an authorized & captured
|
1952 |
+
* charge that has not yet settled (e.g. Authorize.net AIM/CIM)
|
1953 |
+
*
|
1954 |
+
* @since 3.0.0
|
1955 |
+
*
|
1956 |
+
* @param \WC_Order $order order
|
1957 |
+
* @param Payment_Gateway_API_Response $response refund response
|
1958 |
+
* @return boolean true if a void should be performed for the given order/response
|
1959 |
+
*/
|
1960 |
+
protected function maybe_void_instead_of_refund( $order, $response ) {
|
1961 |
+
|
1962 |
+
return false;
|
1963 |
+
}
|
1964 |
+
|
1965 |
+
|
1966 |
+
/**
|
1967 |
+
* Processes a void order.
|
1968 |
+
*
|
1969 |
+
* @since 3.0.0
|
1970 |
+
*
|
1971 |
+
* @param \WC_Order $order order object (with refund class member already added)
|
1972 |
+
* @return bool|\WP_Error true on success, or a WP_Error object on failure/error
|
1973 |
+
*/
|
1974 |
+
protected function process_void( \WC_Order $order ) {
|
1975 |
+
|
1976 |
+
// partial voids are not supported
|
1977 |
+
if ( $order->refund->amount != $order->get_total() ) {
|
1978 |
+
return new \WP_Error( 'wc_' . $this->get_id() . '_void_error', esc_html__( 'Oops, you cannot partially void this order. Please use the full order amount.', 'woocommerce-square' ), 500 );
|
1979 |
+
}
|
1980 |
+
|
1981 |
+
try {
|
1982 |
+
|
1983 |
+
$response = $this->get_api()->void( $order );
|
1984 |
+
|
1985 |
+
if ( $response->transaction_approved() ) {
|
1986 |
+
|
1987 |
+
// add standard void-specific transaction data
|
1988 |
+
$this->add_void_data( $order, $response );
|
1989 |
+
|
1990 |
+
// update order status to "refunded" and add an order note
|
1991 |
+
$this->mark_order_as_voided( $order, $response );
|
1992 |
+
|
1993 |
+
return true;
|
1994 |
+
|
1995 |
+
} else {
|
1996 |
+
|
1997 |
+
$error = $this->get_void_failed_wp_error( $response->get_status_code(), $response->get_status_message() );
|
1998 |
+
|
1999 |
+
$order->add_order_note( $error->get_error_message() );
|
2000 |
+
|
2001 |
+
return $error;
|
2002 |
+
}
|
2003 |
+
|
2004 |
+
} catch ( \Exception $e ) {
|
2005 |
+
|
2006 |
+
$error = $this->get_void_failed_wp_error( $e->getCode(), $e->getMessage() );
|
2007 |
+
|
2008 |
+
$order->add_order_note( $error->get_error_message() );
|
2009 |
+
|
2010 |
+
return $error;
|
2011 |
+
}
|
2012 |
+
}
|
2013 |
+
|
2014 |
+
|
2015 |
+
/**
|
2016 |
+
* Adds the standard void transaction data to the order.
|
2017 |
+
*
|
2018 |
+
* @since 3.0.0
|
2019 |
+
*
|
2020 |
+
* @param \WC_Order $order the order object
|
2021 |
+
* @param Payment_Gateway_API_Response $response transaction response
|
2022 |
+
*/
|
2023 |
+
protected function add_void_data( \WC_Order $order, $response ) {
|
2024 |
+
|
2025 |
+
// indicate the order was voided along with the amount
|
2026 |
+
$this->update_order_meta( $order, 'void_amount', $order->refund->amount );
|
2027 |
+
|
2028 |
+
// add refund transaction ID
|
2029 |
+
if ( $response && $response->get_transaction_id() ) {
|
2030 |
+
$this->add_order_meta( $order, 'void_trans_id', $response->get_transaction_id() );
|
2031 |
+
}
|
2032 |
+
}
|
2033 |
+
|
2034 |
+
/**
|
2035 |
+
* Builds the WP_Error object for a failed void.
|
2036 |
+
*
|
2037 |
+
* @since 3.0.0
|
2038 |
+
*
|
2039 |
+
* @param int|string $error_code error code
|
2040 |
+
* @param string $error_message error message
|
2041 |
+
* @return \WP_Error suitable for returning from the process_refund() method
|
2042 |
+
*/
|
2043 |
+
protected function get_void_failed_wp_error( $error_code, $error_message ) {
|
2044 |
+
|
2045 |
+
if ( $error_code ) {
|
2046 |
+
$message = sprintf(
|
2047 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - error code, %3$s - error message. Void as in to void an order. */
|
2048 |
+
esc_html__( '%1$s Void Failed: %2$s - %3$s', 'woocommerce-square' ),
|
2049 |
+
$this->get_method_title(),
|
2050 |
+
$error_code,
|
2051 |
+
$error_message
|
2052 |
+
);
|
2053 |
+
} else {
|
2054 |
+
$message = sprintf(
|
2055 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - error message. Void as in to void an order. */
|
2056 |
+
esc_html__( '%1$s Void Failed: %2$s', 'woocommerce-square' ),
|
2057 |
+
$this->get_method_title(),
|
2058 |
+
$error_message
|
2059 |
+
);
|
2060 |
+
}
|
2061 |
+
|
2062 |
+
return new \WP_Error( 'wc_' . $this->get_id() . '_void_failed', $message );
|
2063 |
+
}
|
2064 |
+
|
2065 |
+
|
2066 |
+
/**
|
2067 |
+
* Marks an order as voided.
|
2068 |
+
*
|
2069 |
+
* Because WC has no status for "void", we use refunded.
|
2070 |
+
*
|
2071 |
+
* @since 3.0.0
|
2072 |
+
*
|
2073 |
+
* @param \WC_Order $order order object
|
2074 |
+
* @param Payment_Gateway_API_Response $response object
|
2075 |
+
*/
|
2076 |
+
public function mark_order_as_voided( $order, $response ) {
|
2077 |
+
|
2078 |
+
$message = sprintf(
|
2079 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - a monetary amount. Void as in to void an order. */
|
2080 |
+
esc_html__( '%1$s Void in the amount of %2$s approved.', 'woocommerce-square' ),
|
2081 |
+
$this->get_method_title(),
|
2082 |
+
wc_price( $order->refund->amount, array( 'currency' => Order_Compatibility::get_prop( $order, 'currency', 'view' ) ) )
|
2083 |
+
);
|
2084 |
+
|
2085 |
+
// adds the transaction id (if any) to the order note
|
2086 |
+
if ( $response->get_transaction_id() ) {
|
2087 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
2088 |
+
}
|
2089 |
+
|
2090 |
+
// mark order as cancelled, since no money was actually transferred
|
2091 |
+
if ( ! $order->has_status( 'cancelled' ) ) {
|
2092 |
+
|
2093 |
+
$this->voided_order_message = $message;
|
2094 |
+
|
2095 |
+
add_filter( 'woocommerce_order_fully_refunded_status', array( $this, 'maybe_cancel_voided_order' ), 10, 2 );
|
2096 |
+
|
2097 |
+
} else {
|
2098 |
+
|
2099 |
+
$order->add_order_note( $message );
|
2100 |
+
}
|
2101 |
+
}
|
2102 |
+
|
2103 |
+
|
2104 |
+
/**
|
2105 |
+
* Maybe change the order status for a voided order to cancelled
|
2106 |
+
*
|
2107 |
+
* @hooked woocommerce_order_fully_refunded_status filter
|
2108 |
+
*
|
2109 |
+
* @see Payment_Gateway::mark_order_as_voided()
|
2110 |
+
* @since 3.0.0
|
2111 |
+
* @param string $order_status default order status for fully refunded orders
|
2112 |
+
* @param int $order_id order ID
|
2113 |
+
* @return string 'cancelled'
|
2114 |
+
*/
|
2115 |
+
public function maybe_cancel_voided_order( $order_status, $order_id ) {
|
2116 |
+
|
2117 |
+
if ( empty( $this->voided_order_message ) ) {
|
2118 |
+
return $order_status;
|
2119 |
+
}
|
2120 |
+
|
2121 |
+
$order = wc_get_order( $order_id );
|
2122 |
+
|
2123 |
+
// no way to set the order note with the status change
|
2124 |
+
$order->add_order_note( $this->voided_order_message );
|
2125 |
+
|
2126 |
+
return 'cancelled';
|
2127 |
+
}
|
2128 |
+
|
2129 |
+
|
2130 |
+
/**
|
2131 |
+
* Returns the $order object with a unique transaction ref member added.
|
2132 |
+
*
|
2133 |
+
* @since 3.0.0
|
2134 |
+
*
|
2135 |
+
* @param \WC_Order $order the order object
|
2136 |
+
* @return \WC_Order order object with member named unique_transaction_ref
|
2137 |
+
*/
|
2138 |
+
protected function get_order_with_unique_transaction_ref( $order ) {
|
2139 |
+
|
2140 |
+
$order_id = Order_Compatibility::get_prop( $order, 'id' );
|
2141 |
+
|
2142 |
+
// generate a unique retry count
|
2143 |
+
if ( is_numeric( $this->get_order_meta( $order_id, 'retry_count' ) ) ) {
|
2144 |
+
$retry_count = $this->get_order_meta( $order_id, 'retry_count' );
|
2145 |
+
|
2146 |
+
$retry_count++;
|
2147 |
+
} else {
|
2148 |
+
$retry_count = 0;
|
2149 |
+
}
|
2150 |
+
|
2151 |
+
// keep track of the retry count
|
2152 |
+
$this->update_order_meta( $order, 'retry_count', $retry_count );
|
2153 |
+
|
2154 |
+
// generate a unique transaction ref based on the order number and retry count, for gateways that require a unique identifier for every transaction request
|
2155 |
+
$order->unique_transaction_ref = ltrim( $order->get_order_number(), esc_html_x( '#', 'hash before order number', 'woocommerce-square' ) ) . ( $retry_count > 0 ? '-' . $retry_count : '' );
|
2156 |
+
|
2157 |
+
return $order;
|
2158 |
+
}
|
2159 |
+
|
2160 |
+
|
2161 |
+
/**
|
2162 |
+
* Called after an unsuccessful transaction attempt.
|
2163 |
+
*
|
2164 |
+
* @since 3.0.0
|
2165 |
+
*
|
2166 |
+
* @param \WC_Order $order the order
|
2167 |
+
* @param Payment_Gateway_API_Response $response the transaction response
|
2168 |
+
* @return false
|
2169 |
+
*/
|
2170 |
+
protected function do_transaction_failed_result( \WC_Order $order, Payment_Gateway_API_Response $response ) {
|
2171 |
+
|
2172 |
+
$order_note = '';
|
2173 |
+
|
2174 |
+
// build the order note with what data we have
|
2175 |
+
if ( $response->get_status_code() && $response->get_status_message() ) {
|
2176 |
+
/* translators: Placeholders: %1$s - status code, %2$s - status message */
|
2177 |
+
$order_note = sprintf( esc_html__( 'Status code %1$s: %2$s', 'woocommerce-square' ), $response->get_status_code(), $response->get_status_message() );
|
2178 |
+
} elseif ( $response->get_status_code() ) {
|
2179 |
+
/* translators: Placeholders: %s - status code */
|
2180 |
+
$order_note = sprintf( esc_html__( 'Status code: %s', 'woocommerce-square' ), $response->get_status_code() );
|
2181 |
+
} elseif ( $response->get_status_message() ) {
|
2182 |
+
/* translators: Placeholders; %s - status message */
|
2183 |
+
$order_note = sprintf( esc_html__( 'Status message: %s', 'woocommerce-square' ), $response->get_status_message() );
|
2184 |
+
}
|
2185 |
+
|
2186 |
+
// add transaction id if there is one
|
2187 |
+
if ( $response->get_transaction_id() ) {
|
2188 |
+
$order_note .= ' ' . sprintf( esc_html__( 'Transaction ID %s', 'woocommerce-square' ), $response->get_transaction_id() );
|
2189 |
+
}
|
2190 |
+
|
2191 |
+
$this->mark_order_as_failed( $order, $order_note, $response );
|
2192 |
+
|
2193 |
+
return false;
|
2194 |
+
}
|
2195 |
+
|
2196 |
+
|
2197 |
+
/**
|
2198 |
+
* Adds the standard transaction data to the order.
|
2199 |
+
*
|
2200 |
+
* @since 3.0.0
|
2201 |
+
*
|
2202 |
+
* @param \WC_Order $order the order object
|
2203 |
+
* @param Payment_Gateway_API_Response|null $response optional transaction response
|
2204 |
+
*/
|
2205 |
+
public function add_transaction_data( $order, $response = null ) {
|
2206 |
+
|
2207 |
+
// transaction id if available
|
2208 |
+
if ( $response && $response->get_transaction_id() ) {
|
2209 |
+
|
2210 |
+
$this->update_order_meta( $order, 'trans_id', $response->get_transaction_id() );
|
2211 |
+
|
2212 |
+
update_post_meta( Order_Compatibility::get_prop( $order, 'id' ), '_transaction_id', $response->get_transaction_id() );
|
2213 |
+
}
|
2214 |
+
|
2215 |
+
// transaction date
|
2216 |
+
$this->update_order_meta( $order, 'trans_date', current_time( 'mysql' ) );
|
2217 |
+
|
2218 |
+
// if there's more than one environment
|
2219 |
+
if ( count( $this->get_environments() ) > 1 ) {
|
2220 |
+
$this->update_order_meta( $order, 'environment', $this->get_environment() );
|
2221 |
+
}
|
2222 |
+
|
2223 |
+
// customer data
|
2224 |
+
if ( $this->supports_customer_id() ) {
|
2225 |
+
$this->add_customer_data( $order, $response );
|
2226 |
+
}
|
2227 |
+
|
2228 |
+
if ( isset( $order->payment->token ) && $order->payment->token ) {
|
2229 |
+
$this->update_order_meta( $order, 'payment_token', $order->payment->token );
|
2230 |
+
}
|
2231 |
+
|
2232 |
+
// account number
|
2233 |
+
if ( isset( $order->payment->account_number ) && $order->payment->account_number ) {
|
2234 |
+
$this->update_order_meta( $order, 'account_four', substr( $order->payment->account_number, -4 ) );
|
2235 |
+
}
|
2236 |
+
|
2237 |
+
if ( $this->is_credit_card_gateway() ) {
|
2238 |
+
|
2239 |
+
// credit card gateway data
|
2240 |
+
if ( $response && $response instanceof Payment_Gateway_API_Authorization_Response ) {
|
2241 |
+
|
2242 |
+
$this->update_order_meta( $order, 'authorization_amount', $order->payment_total );
|
2243 |
+
|
2244 |
+
if ( $response->get_authorization_code() ) {
|
2245 |
+
$this->update_order_meta( $order, 'authorization_code', $response->get_authorization_code() );
|
2246 |
+
}
|
2247 |
+
|
2248 |
+
if ( $order->payment_total > 0 ) {
|
2249 |
+
|
2250 |
+
// mark as captured
|
2251 |
+
if ( $this->perform_credit_card_charge( $order ) ) {
|
2252 |
+
$captured = 'yes';
|
2253 |
+
} else {
|
2254 |
+
$captured = 'no';
|
2255 |
+
}
|
2256 |
+
|
2257 |
+
$this->update_order_meta( $order, 'charge_captured', $captured );
|
2258 |
+
}
|
2259 |
+
}
|
2260 |
+
|
2261 |
+
if ( isset( $order->payment->exp_year ) && $order->payment->exp_year && isset( $order->payment->exp_month ) && $order->payment->exp_month ) {
|
2262 |
+
$this->update_order_meta( $order, 'card_expiry_date', $order->payment->exp_year . '-' . $order->payment->exp_month );
|
2263 |
+
}
|
2264 |
+
|
2265 |
+
if ( isset( $order->payment->card_type ) && $order->payment->card_type ) {
|
2266 |
+
$this->update_order_meta( $order, 'card_type', $order->payment->card_type );
|
2267 |
+
}
|
2268 |
+
}
|
2269 |
+
|
2270 |
+
/**
|
2271 |
+
* Payment Gateway Add Transaction Data Action.
|
2272 |
+
*
|
2273 |
+
* Fired after a transaction is processed and provides actors a way to add additional
|
2274 |
+
* transactional data to an order given the transaction response object.
|
2275 |
+
*
|
2276 |
+
* @since 3.0.0
|
2277 |
+
*
|
2278 |
+
* @param \WC_Order $order order object
|
2279 |
+
* @param Payment_Gateway_API_Response|null $response transaction response
|
2280 |
+
* @param Payment_Gateway $this instance
|
2281 |
+
*/
|
2282 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_add_transaction_data', $order, $response, $this );
|
2283 |
+
}
|
2284 |
+
|
2285 |
+
|
2286 |
+
/**
|
2287 |
+
* Adds any gateway-specific transaction data to the order.
|
2288 |
+
*
|
2289 |
+
* @since 3.0.0
|
2290 |
+
*
|
2291 |
+
* @param \WC_Order $order the order object
|
2292 |
+
* @param SquareFramework\PaymentGateway\Api\Payment_Gateway_API_Customer_Response $response the transaction response
|
2293 |
+
*/
|
2294 |
+
public function add_payment_gateway_transaction_data( $order, $response ) {
|
2295 |
+
// Optional method
|
2296 |
+
}
|
2297 |
+
|
2298 |
+
|
2299 |
+
/**
|
2300 |
+
* Add customer data to an order/user if the gateway supports the customer ID
|
2301 |
+
* response
|
2302 |
+
*
|
2303 |
+
* @since 3.0.0
|
2304 |
+
*
|
2305 |
+
* @param \WC_Order $order order
|
2306 |
+
* @param SquareFramework\PaymentGateway\Api\Payment_Gateway_API_Customer_Response $response
|
2307 |
+
*/
|
2308 |
+
protected function add_customer_data( $order, $response = null ) {
|
2309 |
+
|
2310 |
+
$user_id = $order->get_user_id();
|
2311 |
+
|
2312 |
+
if ( $response && method_exists( $response, 'get_customer_id' ) && $response->get_customer_id() ) {
|
2313 |
+
|
2314 |
+
$order->customer_id = $customer_id = $response->get_customer_id();
|
2315 |
+
|
2316 |
+
} else {
|
2317 |
+
|
2318 |
+
// default to the customer ID set on the order
|
2319 |
+
$customer_id = $order->customer_id;
|
2320 |
+
}
|
2321 |
+
|
2322 |
+
// update the order with the customer ID, note environment is not appended here because it's already available
|
2323 |
+
// on the `environment` order meta
|
2324 |
+
$this->update_order_meta( $order, 'customer_id', $customer_id );
|
2325 |
+
|
2326 |
+
// update the user
|
2327 |
+
if ( 0 != $user_id ) {
|
2328 |
+
$this->update_customer_id( $user_id, $customer_id );
|
2329 |
+
}
|
2330 |
+
}
|
2331 |
+
|
2332 |
+
|
2333 |
+
/**
|
2334 |
+
* Gets the order note message for approved credit card transactions.
|
2335 |
+
*
|
2336 |
+
* @since 3.0.0
|
2337 |
+
*
|
2338 |
+
* @param \WC_Order $order order object
|
2339 |
+
* @param Payment_Gateway_API_Response $response response object
|
2340 |
+
* @return string
|
2341 |
+
* @throws \Exception
|
2342 |
+
*/
|
2343 |
+
public function get_credit_card_transaction_approved_message( \WC_Order $order, $response ) {
|
2344 |
+
|
2345 |
+
$last_four = ! empty( $order->payment->last_four ) ? $order->payment->last_four : substr( $order->payment->account_number, -4 );
|
2346 |
+
|
2347 |
+
// use direct card type if set, or try to guess it from card number
|
2348 |
+
if ( ! empty( $order->payment->card_type ) ) {
|
2349 |
+
$card_type = $order->payment->card_type;
|
2350 |
+
} elseif ( $first_four = substr( $order->payment->account_number, 0, 4 ) ) {
|
2351 |
+
$card_type = Payment_Gateway_Helper::card_type_from_account_number( $first_four );
|
2352 |
+
} else {
|
2353 |
+
$card_type = 'card';
|
2354 |
+
}
|
2355 |
+
|
2356 |
+
$message = sprintf(
|
2357 |
+
/* translators: Placeholders: %1$s - payment method title, %2$s - environment ("Test"), %3$s - transaction type (authorization/charge) */
|
2358 |
+
esc_html__( '%1$s %2$s %3$s Approved', 'woocommerce-square' ),
|
2359 |
+
$this->get_method_title(),
|
2360 |
+
$this->is_test_environment() ? esc_html_x( 'Test', 'noun, software environment', 'woocommerce-square' ) : '',
|
2361 |
+
$this->perform_credit_card_authorization( $order ) ? esc_html_x( 'Authorization', 'credit card transaction type', 'woocommerce-square' ) : esc_html_x( 'Charge', 'noun, credit card transaction type', 'woocommerce-square' )
|
2362 |
+
);
|
2363 |
+
|
2364 |
+
if ( $last_four ) {
|
2365 |
+
|
2366 |
+
$message .= ': ' . sprintf(
|
2367 |
+
/* translators: Placeholders: %1$s - credit card type (MasterCard, Visa, etc...), %2$s - last four digits of the card */
|
2368 |
+
esc_html__( '%1$s ending in %2$s', 'woocommerce-square' ),
|
2369 |
+
Payment_Gateway_Helper::payment_type_to_name( $card_type ),
|
2370 |
+
$last_four
|
2371 |
+
);
|
2372 |
+
}
|
2373 |
+
|
2374 |
+
// add the expiry date if it is available
|
2375 |
+
if ( ! empty( $order->payment->exp_month ) && ! empty( $order->payment->exp_year ) ) {
|
2376 |
+
|
2377 |
+
$message .= ' ' . sprintf(
|
2378 |
+
/** translators: Placeholders: %s - credit card expiry date */
|
2379 |
+
esc_html__( '(expires %s)', 'woocommerce-square' ),
|
2380 |
+
$order->payment->exp_month . '/' . substr( $order->payment->exp_year, -2 )
|
2381 |
+
);
|
2382 |
+
}
|
2383 |
+
|
2384 |
+
// adds the transaction id (if any) to the order note
|
2385 |
+
if ( $response->get_transaction_id() ) {
|
2386 |
+
/* translators: Placeholders: %s - transaction ID */
|
2387 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
2388 |
+
}
|
2389 |
+
|
2390 |
+
/**
|
2391 |
+
* Direct Gateway Credit Card Transaction Approved Order Note Filter.
|
2392 |
+
*
|
2393 |
+
* Allow actors to modify the order note added when a Credit Card transaction
|
2394 |
+
* is approved.
|
2395 |
+
*
|
2396 |
+
* @since 3.0.0
|
2397 |
+
*
|
2398 |
+
* @param string $message order note
|
2399 |
+
* @param \WC_Order $order order object
|
2400 |
+
* @param Payment_Gateway_API_Response $response transaction response
|
2401 |
+
* @param Payment_Gateway_Direct $this instance
|
2402 |
+
*/
|
2403 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_credit_card_transaction_approved_order_note', $message, $order, $response, $this );
|
2404 |
+
}
|
2405 |
+
|
2406 |
+
/**
|
2407 |
+
* Marks the given order as 'on-hold', set an order note and display a message to the customer.
|
2408 |
+
*
|
2409 |
+
* @since 3.0.0
|
2410 |
+
*
|
2411 |
+
* @param \WC_Order $order the order
|
2412 |
+
* @param string $message a message to display within the order note
|
2413 |
+
* @param Payment_Gateway_API_Response $response optional, the transaction response object
|
2414 |
+
*/
|
2415 |
+
public function mark_order_as_held( $order, $message, $response = null ) {
|
2416 |
+
|
2417 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - message (probably reason for the transaction being held for review) */
|
2418 |
+
$order_note = sprintf( esc_html__( '%1$s Transaction Held for Review (%2$s)', 'woocommerce-square' ), $this->get_method_title(), $message );
|
2419 |
+
|
2420 |
+
/**
|
2421 |
+
* Held Order Status Filter.
|
2422 |
+
*
|
2423 |
+
* This filter is deprecated. Use wc_<gateway_id>_held_order_status instead.
|
2424 |
+
*
|
2425 |
+
* @since 3.0.0
|
2426 |
+
*
|
2427 |
+
* @param string $order_status 'on-hold' by default
|
2428 |
+
* @param \WC_Order $order WC order
|
2429 |
+
* @param Payment_Gateway_API_Response $response instance
|
2430 |
+
* @param Payment_Gateway $gateway gateway instance
|
2431 |
+
*/
|
2432 |
+
$order_status = apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_held_order_status', 'on-hold', $order, $response, $this );
|
2433 |
+
|
2434 |
+
/**
|
2435 |
+
* Filters the order status that's considered to be "held".
|
2436 |
+
*
|
2437 |
+
* @since 3.0.0
|
2438 |
+
*
|
2439 |
+
* @param string $status held order status
|
2440 |
+
* @param \WC_Order $order order object
|
2441 |
+
* @param Payment_Gateway_API_Response|null $response API response object, if any
|
2442 |
+
*/
|
2443 |
+
$order_status = apply_filters( 'wc_' . $this->get_id() . '_held_order_status', $order_status, $order, $response );
|
2444 |
+
|
2445 |
+
// mark order as held
|
2446 |
+
if ( ! $order->has_status( $order_status ) ) {
|
2447 |
+
$order->update_status( $order_status, $order_note );
|
2448 |
+
} else {
|
2449 |
+
$order->add_order_note( $order_note );
|
2450 |
+
}
|
2451 |
+
|
2452 |
+
// user message
|
2453 |
+
$user_message = '';
|
2454 |
+
if ( $response && $this->is_detailed_customer_decline_messages_enabled() ) {
|
2455 |
+
$user_message = $response->get_user_message();
|
2456 |
+
}
|
2457 |
+
|
2458 |
+
if ( ! $user_message || ( $this->supports_credit_card_authorization() && $this->perform_credit_card_authorization( $order ) ) ) {
|
2459 |
+
$user_message = esc_html__( 'Your order has been received and is being reviewed. Thank you for your business.', 'woocommerce-square' );
|
2460 |
+
}
|
2461 |
+
|
2462 |
+
if ( isset( WC()->session ) ) {
|
2463 |
+
WC()->session->held_order_received_text = $user_message;
|
2464 |
+
}
|
2465 |
+
}
|
2466 |
+
|
2467 |
+
|
2468 |
+
/**
|
2469 |
+
* Maybe render custom order received text on the thank you page when
|
2470 |
+
* an order is held
|
2471 |
+
*
|
2472 |
+
* If detailed customer decline messages are enabled, this message may
|
2473 |
+
* additionally include more detailed information.
|
2474 |
+
*
|
2475 |
+
* @since 3.0.0
|
2476 |
+
*
|
2477 |
+
* @param string $text order received text
|
2478 |
+
* @param \WC_Order|null $order order object
|
2479 |
+
* @return string
|
2480 |
+
*/
|
2481 |
+
public function maybe_render_held_order_received_text( $text, $order ) {
|
2482 |
+
|
2483 |
+
if ( $order && $order->has_status( 'on-hold' ) && isset( WC()->session->held_order_received_text ) ) {
|
2484 |
+
|
2485 |
+
$text = WC()->session->held_order_received_text;
|
2486 |
+
|
2487 |
+
unset( WC()->session->held_order_received_text );
|
2488 |
+
}
|
2489 |
+
|
2490 |
+
return $text;
|
2491 |
+
}
|
2492 |
+
|
2493 |
+
|
2494 |
+
/**
|
2495 |
+
* Marks the given order as failed and set the order note.
|
2496 |
+
*
|
2497 |
+
* @since 3.0.0
|
2498 |
+
*
|
2499 |
+
* @param \WC_Order $order the order
|
2500 |
+
* @param string $error_message a message to display inside the "Payment Failed" order note
|
2501 |
+
* @param Payment_Gateway_API_Response optional $response the transaction response object
|
2502 |
+
*/
|
2503 |
+
public function mark_order_as_failed( $order, $error_message, $response = null ) {
|
2504 |
+
|
2505 |
+
/* translators: Placeholders: %1$s - payment gateway title, %2$s - error message; e.g. Order Note: [Payment method] Payment failed [error] */
|
2506 |
+
$order_note = sprintf( esc_html__( '%1$s Payment Failed (%2$s)', 'woocommerce-square' ), $this->get_method_title(), $error_message );
|
2507 |
+
|
2508 |
+
// Mark order as failed if not already set, otherwise, make sure we add the order note so we can detect when someone fails to check out multiple times
|
2509 |
+
if ( ! $order->has_status( 'failed' ) ) {
|
2510 |
+
$order->update_status( 'failed', $order_note );
|
2511 |
+
} else {
|
2512 |
+
$order->add_order_note( $order_note );
|
2513 |
+
}
|
2514 |
+
|
2515 |
+
$this->add_debug_message( $error_message, 'error' );
|
2516 |
+
|
2517 |
+
// user message
|
2518 |
+
$user_message = '';
|
2519 |
+
if ( $response && $this->is_detailed_customer_decline_messages_enabled() ) {
|
2520 |
+
$user_message = $response->get_user_message();
|
2521 |
+
}
|
2522 |
+
if ( ! $user_message ) {
|
2523 |
+
$user_message = esc_html__( 'An error occurred, please try again or try an alternate form of payment.', 'woocommerce-square' );
|
2524 |
+
}
|
2525 |
+
Square_Helper::wc_add_notice( $user_message, 'error' );
|
2526 |
+
}
|
2527 |
+
|
2528 |
+
/** Customer ID Feature **************************************************/
|
2529 |
+
|
2530 |
+
|
2531 |
+
/**
|
2532 |
+
* Returns true if this is gateway that supports gateway customer IDs
|
2533 |
+
*
|
2534 |
+
* @since 3.0.0
|
2535 |
+
* @return boolean true if the gateway supports gateway customer IDs
|
2536 |
+
*/
|
2537 |
+
public function supports_customer_id() {
|
2538 |
+
|
2539 |
+
return $this->supports( self::FEATURE_CUSTOMER_ID );
|
2540 |
+
}
|
2541 |
+
|
2542 |
+
|
2543 |
+
/**
|
2544 |
+
* Gets/sets the payment gateway customer id, this defaults to wc-{user id}
|
2545 |
+
* and retrieves/stores to the user meta named by get_customer_id_user_meta_name()
|
2546 |
+
* This can be overridden for gateways that use some other value, or made to
|
2547 |
+
* return false for gateways that don't support a customer id.
|
2548 |
+
*
|
2549 |
+
* @since 3.0.0
|
2550 |
+
* @see Payment_Gateway::get_customer_id_user_meta_name()
|
2551 |
+
* @param int $user_id wordpress user identifier
|
2552 |
+
* @param array $args optional additional arguments which can include: environment_id, autocreate (true/false), and order
|
2553 |
+
* @return string payment gateway customer id
|
2554 |
+
*/
|
2555 |
+
public function get_customer_id( $user_id, $args = array() ) {
|
2556 |
+
|
2557 |
+
$defaults = array(
|
2558 |
+
'environment_id' => $this->get_environment(),
|
2559 |
+
'autocreate' => true,
|
2560 |
+
'order' => null,
|
2561 |
+
);
|
2562 |
+
|
2563 |
+
$args = array_merge( $defaults, $args );
|
2564 |
+
|
2565 |
+
// does an id already exist for this user?
|
2566 |
+
$customer_id = get_user_meta( $user_id, $this->get_customer_id_user_meta_name( $args['environment_id'] ), true );
|
2567 |
+
|
2568 |
+
if ( ! $customer_id && $args['autocreate'] ) {
|
2569 |
+
|
2570 |
+
$billing_email = ( $args['order'] ) ? Order_Compatibility::get_prop( $args['order'], 'billing_email' ) : '';
|
2571 |
+
|
2572 |
+
// generate a new customer id. We try to use 'wc-<hash of billing email>'
|
2573 |
+
// if an order is available, on the theory that it will avoid clashing of
|
2574 |
+
// accounts if a customer uses the same merchant account on multiple independent
|
2575 |
+
// shops. Otherwise, we use 'wc-<user_id>-<random>'
|
2576 |
+
if ( $billing_email ) {
|
2577 |
+
$customer_id = 'wc-' . md5( $billing_email );
|
2578 |
+
} else {
|
2579 |
+
$customer_id = uniqid( 'wc-' . $user_id . '-' );
|
2580 |
+
}
|
2581 |
+
|
2582 |
+
$this->update_customer_id( $user_id, $customer_id, $args['environment_id'] );
|
2583 |
+
}
|
2584 |
+
|
2585 |
+
return $customer_id;
|
2586 |
+
}
|
2587 |
+
|
2588 |
+
|
2589 |
+
/**
|
2590 |
+
* Updates the payment gateway customer id for the given $environment, or
|
2591 |
+
* for the plugin current environment
|
2592 |
+
*
|
2593 |
+
* @since 3.0.0
|
2594 |
+
* @see Payment_Gateway::get_customer_id()
|
2595 |
+
* @param int $user_id WP user ID
|
2596 |
+
* @param string $customer_id payment gateway customer id
|
2597 |
+
* @param string $environment_id optional environment id, defaults to current environment
|
2598 |
+
* @return boolean|int false if no change was made (if the new value was the same as previous value) or if the update failed, meta id if the value was different and the update a success
|
2599 |
+
*/
|
2600 |
+
public function update_customer_id( $user_id, $customer_id, $environment_id = null ) {
|
2601 |
+
|
2602 |
+
// default to current environment
|
2603 |
+
if ( is_null( $environment_id ) ) {
|
2604 |
+
$environment_id = $this->get_environment();
|
2605 |
+
}
|
2606 |
+
|
2607 |
+
return update_user_meta( $user_id, $this->get_customer_id_user_meta_name( $environment_id ), $customer_id );
|
2608 |
+
}
|
2609 |
+
|
2610 |
+
|
2611 |
+
/**
|
2612 |
+
* Removes the payment gateway customer id for the given $environment, or
|
2613 |
+
* for the plugin current environment
|
2614 |
+
*
|
2615 |
+
* @since 3.0.0
|
2616 |
+
* @param int $user_id WP user ID
|
2617 |
+
* @param string $environment_id optional environment id, defaults to current environment
|
2618 |
+
* @return boolean true on success, false on failure
|
2619 |
+
*/
|
2620 |
+
public function remove_customer_id( $user_id, $environment_id = null ){
|
2621 |
+
|
2622 |
+
if ( is_null( $environment_id ) ) {
|
2623 |
+
$environment_id = $this->get_environment();
|
2624 |
+
}
|
2625 |
+
|
2626 |
+
// remove the user meta entry so it can be re-created
|
2627 |
+
return delete_user_meta( $user_id, $this->get_customer_id_user_meta_name( $environment_id ) );
|
2628 |
+
}
|
2629 |
+
|
2630 |
+
|
2631 |
+
/**
|
2632 |
+
* Returns a payment gateway customer id for a guest customer. This
|
2633 |
+
* defaults to wc-guest-{order id} but can be overridden for gateways that
|
2634 |
+
* use some other value, or made to return false for gateways that don't
|
2635 |
+
* support a customer id
|
2636 |
+
*
|
2637 |
+
* @since 3.0.0
|
2638 |
+
*
|
2639 |
+
* @param \WC_Order $order order object
|
2640 |
+
* @return string payment gateway guest customer id
|
2641 |
+
*/
|
2642 |
+
public function get_guest_customer_id( \WC_Order $order ) {
|
2643 |
+
|
2644 |
+
// is there a customer id already tied to this order?
|
2645 |
+
$customer_id = $this->get_order_meta( Order_Compatibility::get_prop( $order, 'id' ), 'customer_id' );
|
2646 |
+
|
2647 |
+
if ( $customer_id ) {
|
2648 |
+
return $customer_id;
|
2649 |
+
}
|
2650 |
+
|
2651 |
+
// default
|
2652 |
+
return 'wc-guest-' . Order_Compatibility::get_prop( $order, 'id' );
|
2653 |
+
}
|
2654 |
+
|
2655 |
+
|
2656 |
+
/**
|
2657 |
+
* Returns the payment gateway customer id user meta name for persisting the
|
2658 |
+
* gateway customer id. Defaults to wc_{plugin id}_customer_id for the
|
2659 |
+
* production environment and wc_{plugin id}_customer_id_{environment}
|
2660 |
+
* for other environments. A particular environment can be passed,
|
2661 |
+
* otherwise this will default to the plugin current environment.
|
2662 |
+
*
|
2663 |
+
* This can be overridden and made to return false for gateways that don't
|
2664 |
+
* support a customer id.
|
2665 |
+
*
|
2666 |
+
* @since 3.0.0
|
2667 |
+
* @param string $environment_id optional environment id, defaults to plugin current environment
|
2668 |
+
* @return string payment gateway customer id user meta name
|
2669 |
+
*/
|
2670 |
+
public function get_customer_id_user_meta_name( $environment_id = null ) {
|
2671 |
+
|
2672 |
+
if ( is_null( $environment_id ) ) {
|
2673 |
+
$environment_id = $this->get_environment();
|
2674 |
+
}
|
2675 |
+
|
2676 |
+
// no leading underscore since this is meant to be visible to the admin
|
2677 |
+
return 'wc_' . $this->get_plugin()->get_id() . '_customer_id' . ( ! $this->is_production_environment( $environment_id ) ? '_' . $environment_id : '' );
|
2678 |
+
}
|
2679 |
+
|
2680 |
+
|
2681 |
+
/** Authorization/Charge feature ******************************************/
|
2682 |
+
|
2683 |
+
|
2684 |
+
/**
|
2685 |
+
* Returns true if this is a credit card gateway which supports
|
2686 |
+
* authorization transactions
|
2687 |
+
*
|
2688 |
+
* @since 3.0.0
|
2689 |
+
* @return boolean true if the gateway supports authorization
|
2690 |
+
*/
|
2691 |
+
public function supports_credit_card_authorization() {
|
2692 |
+
return $this->is_credit_card_gateway() && $this->supports( self::FEATURE_CREDIT_CARD_AUTHORIZATION );
|
2693 |
+
}
|
2694 |
+
|
2695 |
+
|
2696 |
+
/**
|
2697 |
+
* Returns true if this is a credit card gateway which supports
|
2698 |
+
* charge transactions
|
2699 |
+
*
|
2700 |
+
* @since 3.0.0
|
2701 |
+
* @return boolean true if the gateway supports charges
|
2702 |
+
*/
|
2703 |
+
public function supports_credit_card_charge() {
|
2704 |
+
return $this->is_credit_card_gateway() && $this->supports( self::FEATURE_CREDIT_CARD_CHARGE );
|
2705 |
+
}
|
2706 |
+
|
2707 |
+
|
2708 |
+
/**
|
2709 |
+
* Determines if this is a credit card gateway that supports charging virtual-only orders.
|
2710 |
+
*
|
2711 |
+
* @since 3.0.0
|
2712 |
+
* @return bool
|
2713 |
+
*/
|
2714 |
+
public function supports_credit_card_charge_virtual() {
|
2715 |
+
return $this->is_credit_card_gateway() && $this->supports( self::FEATURE_CREDIT_CARD_CHARGE_VIRTUAL );
|
2716 |
+
}
|
2717 |
+
|
2718 |
+
|
2719 |
+
/**
|
2720 |
+
* Returns true if the gateway supports capturing a charge
|
2721 |
+
*
|
2722 |
+
* @since 3.0.0
|
2723 |
+
* @return boolean true if the gateway supports capturing a charge
|
2724 |
+
*/
|
2725 |
+
public function supports_credit_card_capture() {
|
2726 |
+
return $this->supports( self::FEATURE_CREDIT_CARD_CAPTURE );
|
2727 |
+
}
|
2728 |
+
|
2729 |
+
|
2730 |
+
/**
|
2731 |
+
* Determines if the gateway supports capturing a partial charge.
|
2732 |
+
*
|
2733 |
+
* @since 3.0.0
|
2734 |
+
*
|
2735 |
+
* @return bool
|
2736 |
+
*/
|
2737 |
+
public function supports_credit_card_partial_capture() {
|
2738 |
+
return $this->supports_credit_card_capture() && $this->supports( self::FEATURE_CREDIT_CARD_PARTIAL_CAPTURE );
|
2739 |
+
}
|
2740 |
+
|
2741 |
+
|
2742 |
+
/**
|
2743 |
+
* Adds any credit card authorization/charge admin fields, allowing the
|
2744 |
+
* administrator to choose between performing authorizations or charges
|
2745 |
+
*
|
2746 |
+
* @since 3.0.0
|
2747 |
+
* @param array $form_fields gateway form fields
|
2748 |
+
* @return array $form_fields gateway form fields
|
2749 |
+
*/
|
2750 |
+
protected function add_authorization_charge_form_fields( $form_fields ) {
|
2751 |
+
|
2752 |
+
assert( $this->supports_credit_card_authorization() && $this->supports_credit_card_charge() );
|
2753 |
+
|
2754 |
+
$form_fields['transaction_type'] = array(
|
2755 |
+
'title' => esc_html__( 'Transaction Type', 'woocommerce-square' ),
|
2756 |
+
'type' => 'select',
|
2757 |
+
'desc_tip' => esc_html__( 'Select how transactions should be processed. Charge submits all transactions for settlement, Authorization simply authorizes the order total for capture later.', 'woocommerce-square' ),
|
2758 |
+
'default' => self::TRANSACTION_TYPE_CHARGE,
|
2759 |
+
'options' => array(
|
2760 |
+
self::TRANSACTION_TYPE_CHARGE => esc_html_x( 'Charge', 'noun, credit card transaction type', 'woocommerce-square' ),
|
2761 |
+
self::TRANSACTION_TYPE_AUTHORIZATION => esc_html_x( 'Authorization', 'credit card transaction type', 'woocommerce-square' ),
|
2762 |
+
),
|
2763 |
+
);
|
2764 |
+
|
2765 |
+
if ( $this->supports_credit_card_charge_virtual() ) {
|
2766 |
+
|
2767 |
+
$form_fields['charge_virtual_orders'] = array(
|
2768 |
+
'label' => esc_html__( 'Charge Virtual-Only Orders', 'woocommerce-square' ),
|
2769 |
+
'type' => 'checkbox',
|
2770 |
+
'description' => esc_html__( 'If the order contains exclusively virtual items, enable this to immediately charge, rather than authorize, the transaction.', 'woocommerce-square' ),
|
2771 |
+
'default' => 'no',
|
2772 |
+
);
|
2773 |
+
}
|
2774 |
+
|
2775 |
+
if ( $this->supports_credit_card_partial_capture() ) {
|
2776 |
+
|
2777 |
+
$form_fields['enable_partial_capture'] = array(
|
2778 |
+
'label' => esc_html__( 'Enable Partial Capture', 'woocommerce-square' ),
|
2779 |
+
'type' => 'checkbox',
|
2780 |
+
'description' => esc_html__( 'Allow orders to be partially captured multiple times.', 'woocommerce-square' ),
|
2781 |
+
'default' => 'no',
|
2782 |
+
);
|
2783 |
+
}
|
2784 |
+
|
2785 |
+
if ( $this->supports_credit_card_capture() ) {
|
2786 |
+
|
2787 |
+
// get a list of the "paid" status names
|
2788 |
+
$paid_statuses = array_map( 'wc_get_order_status_name', (array) wc_get_is_paid_statuses() );
|
2789 |
+
$conjuction = _x( 'or', 'coordinating conjunction for a list of order statuses: on-hold, processing, or completed', 'woocommerce-square' );
|
2790 |
+
|
2791 |
+
$form_fields['enable_paid_capture'] = array(
|
2792 |
+
'label' => __( 'Capture Paid Orders', 'woocommerce-square' ),
|
2793 |
+
'type' => 'checkbox',
|
2794 |
+
'description' => sprintf(
|
2795 |
+
esc_html__( 'Automatically capture orders when they are changed to %s.', 'woocommerce-square' ),
|
2796 |
+
esc_html( ! empty( $paid_statuses ) ? Square_Helper::list_array_items( $paid_statuses, $conjuction ) : __( 'a paid status', 'woocommerce-square' ) )
|
2797 |
+
),
|
2798 |
+
'default' => 'no',
|
2799 |
+
);
|
2800 |
+
}
|
2801 |
+
|
2802 |
+
return $form_fields;
|
2803 |
+
}
|
2804 |
+
|
2805 |
+
|
2806 |
+
/**
|
2807 |
+
* Return the authorization time window in hours. An authorization is considered
|
2808 |
+
* expired if it is older than this.
|
2809 |
+
*
|
2810 |
+
* 30 days (720 hours) is the standard authorization window. Individual gateways
|
2811 |
+
* can override this as necessary.
|
2812 |
+
*
|
2813 |
+
* @since 3.0.0
|
2814 |
+
* @return int hours
|
2815 |
+
*/
|
2816 |
+
public function get_authorization_time_window() {
|
2817 |
+
|
2818 |
+
return 720;
|
2819 |
+
}
|
2820 |
+
|
2821 |
+
|
2822 |
+
/**
|
2823 |
+
* Determines if a credit card transaction should result in a charge.
|
2824 |
+
*
|
2825 |
+
* @since 3.0.0
|
2826 |
+
*
|
2827 |
+
* @param \WC_Order $order Optional. The order being charged
|
2828 |
+
* @return bool
|
2829 |
+
*/
|
2830 |
+
public function perform_credit_card_charge( \WC_Order $order = null ) {
|
2831 |
+
|
2832 |
+
assert( $this->supports_credit_card_charge() );
|
2833 |
+
|
2834 |
+
$perform = self::TRANSACTION_TYPE_CHARGE === $this->transaction_type;
|
2835 |
+
|
2836 |
+
if ( ! $perform && $order && $this->supports_credit_card_charge_virtual() && 'yes' === $this->charge_virtual_orders ) {
|
2837 |
+
$perform = Square_Helper::is_order_virtual( $order );
|
2838 |
+
}
|
2839 |
+
|
2840 |
+
/**
|
2841 |
+
* Filters whether a credit card transaction should result in a charge.
|
2842 |
+
*
|
2843 |
+
* @since 3.0.0
|
2844 |
+
*
|
2845 |
+
* @param bool $perform whether the transaction should result in a charge
|
2846 |
+
* @param \WC_Order|null $order the order being charged
|
2847 |
+
* @param Payment_Gateway $gateway the gateway object
|
2848 |
+
*/
|
2849 |
+
return apply_filters( 'wc_' . $this->get_id() . '_perform_credit_card_charge', $perform, $order, $this );
|
2850 |
+
}
|
2851 |
+
|
2852 |
+
|
2853 |
+
/**
|
2854 |
+
* Determines if a credit card transaction should result in an authorization.
|
2855 |
+
*
|
2856 |
+
* @since 3.0.0
|
2857 |
+
*
|
2858 |
+
* @param \WC_Order $order Optional. The order being authorized
|
2859 |
+
* @return bool
|
2860 |
+
*/
|
2861 |
+
public function perform_credit_card_authorization( \WC_Order $order = null ) {
|
2862 |
+
|
2863 |
+
assert( $this->supports_credit_card_authorization() );
|
2864 |
+
|
2865 |
+
$perform = self::TRANSACTION_TYPE_AUTHORIZATION === $this->transaction_type && ! $this->perform_credit_card_charge( $order );
|
2866 |
+
|
2867 |
+
/**
|
2868 |
+
* Filters whether a credit card transaction should result in an authorization.
|
2869 |
+
*
|
2870 |
+
* @since 3.0.0
|
2871 |
+
* @param bool $perform whether the transaction should result in an authorization
|
2872 |
+
* @param \WC_Order|null $order the order being authorized
|
2873 |
+
* @param Payment_Gateway $gateway the gateway object
|
2874 |
+
*/
|
2875 |
+
return apply_filters( 'wc_' . $this->get_id() . '_perform_credit_card_authorization', $perform, $order, $this );
|
2876 |
+
}
|
2877 |
+
|
2878 |
+
|
2879 |
+
/**
|
2880 |
+
* Determines if partial capture is enabled.
|
2881 |
+
*
|
2882 |
+
* @since 3.0.0
|
2883 |
+
*
|
2884 |
+
* @return bool
|
2885 |
+
*/
|
2886 |
+
public function is_partial_capture_enabled() {
|
2887 |
+
|
2888 |
+
assert( $this->supports_credit_card_partial_capture() );
|
2889 |
+
|
2890 |
+
/**
|
2891 |
+
* Filters whether partial capture is enabled.
|
2892 |
+
*
|
2893 |
+
* @since 3.0.0
|
2894 |
+
*
|
2895 |
+
* @param bool $enabled whether partial capture is enabled
|
2896 |
+
* @param Payment_Gateway $gateway gateway object
|
2897 |
+
*/
|
2898 |
+
return apply_filters( 'wc_' . $this->get_id() . '_partial_capture_enabled', 'yes' === $this->enable_partial_capture, $this );
|
2899 |
+
}
|
2900 |
+
|
2901 |
+
|
2902 |
+
/**
|
2903 |
+
* Determines if orders should be captured when switched to a "paid" status.
|
2904 |
+
*
|
2905 |
+
* @since 3.0.0
|
2906 |
+
*
|
2907 |
+
* @return bool
|
2908 |
+
*/
|
2909 |
+
public function is_paid_capture_enabled() {
|
2910 |
+
|
2911 |
+
/**
|
2912 |
+
* Filters whether orders should be captured when switched to a "paid" status.
|
2913 |
+
*
|
2914 |
+
* @since 3.0.0
|
2915 |
+
*
|
2916 |
+
* @param bool $enabled whether "paid" capture is enabled
|
2917 |
+
* @param Payment_Gateway $gateway gateway object
|
2918 |
+
*/
|
2919 |
+
return apply_filters( 'wc_' . $this->get_id() . '_paid_capture_enabled', 'yes' === $this->enable_paid_capture, $this );
|
2920 |
+
}
|
2921 |
+
|
2922 |
+
|
2923 |
+
/** Add Payment Method feature ********************************************/
|
2924 |
+
|
2925 |
+
|
2926 |
+
/**
|
2927 |
+
* Determines if the gateway supports the add payment method feature.
|
2928 |
+
*
|
2929 |
+
* @since 3.0.0
|
2930 |
+
*
|
2931 |
+
* @return bool
|
2932 |
+
*/
|
2933 |
+
public function supports_add_payment_method() {
|
2934 |
+
|
2935 |
+
return $this->supports( self::FEATURE_ADD_PAYMENT_METHOD );
|
2936 |
+
}
|
2937 |
+
|
2938 |
+
|
2939 |
+
// TODO: generalize the direct methods
|
2940 |
+
|
2941 |
+
|
2942 |
+
/** Card Types feature ******************************************************/
|
2943 |
+
|
2944 |
+
|
2945 |
+
/**
|
2946 |
+
* Returns true if the gateway supports card_types: allows the admin to
|
2947 |
+
* configure card type icons to display at checkout
|
2948 |
+
*
|
2949 |
+
* @since 3.0.0
|
2950 |
+
* @return boolean true if the gateway supports card_types
|
2951 |
+
*/
|
2952 |
+
public function supports_card_types() {
|
2953 |
+
return $this->is_credit_card_gateway() && $this->supports( self::FEATURE_CARD_TYPES );
|
2954 |
+
}
|
2955 |
+
|
2956 |
+
|
2957 |
+
/**
|
2958 |
+
* Returns the array of accepted card types if this is a credit card gateway
|
2959 |
+
* that supports card types. Return format is 'VISA', 'MC', 'AMEX', etc
|
2960 |
+
*
|
2961 |
+
* @since 3.0.0
|
2962 |
+
* @see get_available_card_types()
|
2963 |
+
* @return array of accepted card types, ie 'VISA', 'MC', 'AMEX', etc
|
2964 |
+
*/
|
2965 |
+
public function get_card_types() {
|
2966 |
+
|
2967 |
+
assert( $this->supports_card_types() );
|
2968 |
+
|
2969 |
+
return $this->card_types;
|
2970 |
+
}
|
2971 |
+
|
2972 |
+
|
2973 |
+
/**
|
2974 |
+
* Adds any card types form fields, allowing the admin to configure the card
|
2975 |
+
* types icons displayed during checkout
|
2976 |
+
*
|
2977 |
+
* @since 3.0.0
|
2978 |
+
* @param array $form_fields gateway form fields
|
2979 |
+
* @return array $form_fields gateway form fields
|
2980 |
+
*/
|
2981 |
+
protected function add_card_types_form_fields( $form_fields ) {
|
2982 |
+
|
2983 |
+
assert( $this->supports_card_types() );
|
2984 |
+
|
2985 |
+
$form_fields['card_types'] = array(
|
2986 |
+
'title' => esc_html__( 'Accepted Card Logos', 'woocommerce-square' ),
|
2987 |
+
'type' => 'multiselect',
|
2988 |
+
'desc_tip' => __( 'These are the card logos that are displayed to customers as accepted during checkout.', 'woocommerce-square' ),
|
2989 |
+
'description' => sprintf(
|
2990 |
+
/* translators: Placeholders: %1$s - <strong> tag, %2$s - </strong> tag */
|
2991 |
+
__( 'This setting %1$sdoes not%2$s change which card types the gateway will accept. Accepted cards are configured from your payment processor account.', 'woocommerce-square' ),
|
2992 |
+
'<strong>',
|
2993 |
+
'</strong>'
|
2994 |
+
),
|
2995 |
+
'default' => array_keys( $this->get_available_card_types() ),
|
2996 |
+
'class' => 'wc-enhanced-select',
|
2997 |
+
'css' => 'width: 350px;',
|
2998 |
+
'options' => $this->get_available_card_types(),
|
2999 |
+
);
|
3000 |
+
|
3001 |
+
return $form_fields;
|
3002 |
+
}
|
3003 |
+
|
3004 |
+
|
3005 |
+
/**
|
3006 |
+
* Returns available card types, ie 'VISA' => 'Visa', 'MC' => 'MasterCard', etc
|
3007 |
+
*
|
3008 |
+
* @since 3.0.0
|
3009 |
+
* @return array associative array of card type to display name
|
3010 |
+
*/
|
3011 |
+
public function get_available_card_types() {
|
3012 |
+
|
3013 |
+
assert( $this->supports_card_types() );
|
3014 |
+
|
3015 |
+
// default available card types
|
3016 |
+
if ( ! isset( $this->available_card_types ) ) {
|
3017 |
+
|
3018 |
+
$this->available_card_types = array(
|
3019 |
+
'VISA' => esc_html_x( 'Visa', 'credit card type', 'woocommerce-square' ),
|
3020 |
+
'MC' => esc_html_x( 'MasterCard', 'credit card type', 'woocommerce-square' ),
|
3021 |
+
'AMEX' => esc_html_x( 'American Express', 'credit card type', 'woocommerce-square' ),
|
3022 |
+
'DISC' => esc_html_x( 'Discover', 'credit card type', 'woocommerce-square' ),
|
3023 |
+
'DINERS' => esc_html_x( 'Diners', 'credit card type', 'woocommerce-square' ),
|
3024 |
+
'JCB' => esc_html_x( 'JCB', 'credit card type', 'woocommerce-square' ),
|
3025 |
+
);
|
3026 |
+
|
3027 |
+
}
|
3028 |
+
|
3029 |
+
/**
|
3030 |
+
* Payment Gateway Available Card Types Filter.
|
3031 |
+
*
|
3032 |
+
* Allow actors to modify the available card types.
|
3033 |
+
*
|
3034 |
+
* @since 3.0.0
|
3035 |
+
* @param array $available_card_types
|
3036 |
+
*/
|
3037 |
+
return apply_filters( 'wc_' . $this->get_id() . '_available_card_types', $this->available_card_types );
|
3038 |
+
}
|
3039 |
+
|
3040 |
+
|
3041 |
+
/** Tokenization feature **************************************************/
|
3042 |
+
|
3043 |
+
|
3044 |
+
/**
|
3045 |
+
* Returns true if the gateway supports tokenization
|
3046 |
+
*
|
3047 |
+
* @since 3.0.0
|
3048 |
+
* @return boolean true if the gateway supports tokenization
|
3049 |
+
*/
|
3050 |
+
public function supports_tokenization() {
|
3051 |
+
return $this->supports( self::FEATURE_TOKENIZATION );
|
3052 |
+
}
|
3053 |
+
|
3054 |
+
|
3055 |
+
/**
|
3056 |
+
* Returns true if tokenization is enabled
|
3057 |
+
*
|
3058 |
+
* @since 3.0.0
|
3059 |
+
* @return boolean true if tokenization is enabled
|
3060 |
+
*/
|
3061 |
+
public function tokenization_enabled() {
|
3062 |
+
|
3063 |
+
assert( $this->supports_tokenization() );
|
3064 |
+
|
3065 |
+
return 'yes' == $this->tokenization;
|
3066 |
+
}
|
3067 |
+
|
3068 |
+
|
3069 |
+
/**
|
3070 |
+
* Adds any tokenization form fields for the settings page
|
3071 |
+
*
|
3072 |
+
* @since 3.0.0
|
3073 |
+
* @param array $form_fields gateway form fields
|
3074 |
+
* @return array $form_fields gateway form fields
|
3075 |
+
*/
|
3076 |
+
protected function add_tokenization_form_fields( $form_fields ) {
|
3077 |
+
|
3078 |
+
assert( $this->supports_tokenization() );
|
3079 |
+
|
3080 |
+
$form_fields['tokenization'] = array(
|
3081 |
+
/* translators: http://www.cybersource.com/products/payment_security/payment_tokenization/ and https://en.wikipedia.org/wiki/Tokenization_(data_security) */
|
3082 |
+
'title' => esc_html__( 'Tokenization', 'woocommerce-square' ),
|
3083 |
+
'label' => esc_html__( 'Allow customers to securely save their payment details for future checkout.', 'woocommerce-square' ),
|
3084 |
+
'type' => 'checkbox',
|
3085 |
+
'default' => 'no',
|
3086 |
+
);
|
3087 |
+
|
3088 |
+
return $form_fields;
|
3089 |
+
}
|
3090 |
+
|
3091 |
+
/**
|
3092 |
+
* Safely get and trim data from $_REQUEST
|
3093 |
+
*
|
3094 |
+
* @since 3.0.0
|
3095 |
+
* @param string $key array key to get from $_REQUEST array
|
3096 |
+
* @return string value from $_REQUEST or blank string if $_REQUEST[ $key ] is not set
|
3097 |
+
*/
|
3098 |
+
protected function get_request( $key ) {
|
3099 |
+
|
3100 |
+
if ( isset( $_REQUEST[ $key ] ) ) {
|
3101 |
+
return trim( $_REQUEST[ $key ] );
|
3102 |
+
}
|
3103 |
+
|
3104 |
+
return '';
|
3105 |
+
}
|
3106 |
+
|
3107 |
+
|
3108 |
+
/**
|
3109 |
+
* Add API request logging for the gateway. The main plugin class typically handles this, but the payment
|
3110 |
+
* gateway plugin class no-ops the method so each gateway's requests can be logged individually (e.g. credit card)
|
3111 |
+
* and make use of the payment gateway-specific add_debug_message() method
|
3112 |
+
*
|
3113 |
+
* @since 3.0.0
|
3114 |
+
* @see Plugin::add_api_request_logging()
|
3115 |
+
*/
|
3116 |
+
public function add_api_request_logging() {
|
3117 |
+
|
3118 |
+
if ( ! has_action( 'wc_' . $this->get_id() . '_api_request_performed' ) ) {
|
3119 |
+
add_action( 'wc_' . $this->get_id() . '_api_request_performed', array( $this, 'log_api_request' ), 10, 2 );
|
3120 |
+
}
|
3121 |
+
}
|
3122 |
+
|
3123 |
+
|
3124 |
+
/**
|
3125 |
+
* Log gateway API requests/responses
|
3126 |
+
*
|
3127 |
+
* @since 3.0.0
|
3128 |
+
* @param array $request request data, see Base::broadcast_request() for format
|
3129 |
+
* @param array $response response data
|
3130 |
+
*/
|
3131 |
+
public function log_api_request( $request, $response ) {
|
3132 |
+
|
3133 |
+
// request
|
3134 |
+
$this->add_debug_message( $this->get_plugin()->get_api_log_message( $request ), 'message' );
|
3135 |
+
|
3136 |
+
// response
|
3137 |
+
if ( ! empty( $response ) ) {
|
3138 |
+
$this->add_debug_message( $this->get_plugin()->get_api_log_message( $response ), 'message' );
|
3139 |
+
}
|
3140 |
+
}
|
3141 |
+
|
3142 |
+
|
3143 |
+
/**
|
3144 |
+
* Adds debug messages to the page as a WC message/error, and/or to the WC Error log
|
3145 |
+
*
|
3146 |
+
* @since 3.0.0
|
3147 |
+
* @param string $message message to add
|
3148 |
+
* @param string $type how to add the message, options are:
|
3149 |
+
* 'message' (styled as WC message), 'error' (styled as WC Error)
|
3150 |
+
*/
|
3151 |
+
public function add_debug_message( $message, $type = 'message' ) {
|
3152 |
+
|
3153 |
+
// do nothing when debug mode is off or no message
|
3154 |
+
if ( 'off' == $this->debug_off() || ! $message ) {
|
3155 |
+
return;
|
3156 |
+
}
|
3157 |
+
|
3158 |
+
// add log message to WC logger if log/both is enabled
|
3159 |
+
if ( $this->debug_log() ) {
|
3160 |
+
$this->get_plugin()->log( $message, $this->get_id() );
|
3161 |
+
}
|
3162 |
+
|
3163 |
+
// avoid adding notices when performing refunds, these occur in the admin as an Ajax call, so checking the current filter
|
3164 |
+
// is the only reliably way to do so
|
3165 |
+
if ( in_array( 'wp_ajax_woocommerce_refund_line_items', $GLOBALS['wp_current_filter'], true ) ) {
|
3166 |
+
return;
|
3167 |
+
}
|
3168 |
+
|
3169 |
+
// add debug message to woocommerce->errors/messages if checkout or both is enabled, the admin/Ajax check ensures capture charge transactions aren't logged as notices to the front end
|
3170 |
+
if ( ( $this->debug_checkout() || ( 'error' === $type && $this->is_test_environment() ) ) && ( ! is_admin() || wp_doing_ajax() ) ) {
|
3171 |
+
|
3172 |
+
if ( 'message' === $type ) {
|
3173 |
+
|
3174 |
+
Square_Helper::wc_add_notice( str_replace( "\n", "<br/>", htmlspecialchars( $message ) ), 'notice' );
|
3175 |
+
|
3176 |
+
} else {
|
3177 |
+
|
3178 |
+
// defaults to error message
|
3179 |
+
Square_Helper::wc_add_notice( str_replace( "\n", "<br/>", htmlspecialchars( $message ) ), 'error' );
|
3180 |
+
}
|
3181 |
+
}
|
3182 |
+
}
|
3183 |
+
|
3184 |
+
|
3185 |
+
/**
|
3186 |
+
* Get payment currency, either from current order or WC settings
|
3187 |
+
*
|
3188 |
+
* @since 3.0.0
|
3189 |
+
* @return string three-letter currency code
|
3190 |
+
*/
|
3191 |
+
protected function get_payment_currency() {
|
3192 |
+
|
3193 |
+
$currency = get_woocommerce_currency();
|
3194 |
+
$order_id = $this->get_checkout_pay_page_order_id();
|
3195 |
+
|
3196 |
+
// Gets currency for the current order, that is about to be paid for
|
3197 |
+
if ( $order_id ) {
|
3198 |
+
|
3199 |
+
$order = wc_get_order( $order_id );
|
3200 |
+
$currency = Order_Compatibility::get_prop( $order, 'currency', 'view' );
|
3201 |
+
}
|
3202 |
+
|
3203 |
+
return $currency;
|
3204 |
+
}
|
3205 |
+
|
3206 |
+
|
3207 |
+
/**
|
3208 |
+
* Returns true if $currency is accepted by this gateway
|
3209 |
+
*
|
3210 |
+
* @since 3.0.0
|
3211 |
+
* @param string $currency optional three-letter currency code, defaults to
|
3212 |
+
* order currency (if available) or currently configured WooCommerce
|
3213 |
+
* currency
|
3214 |
+
* @return boolean true if $currency is accepted, false otherwise
|
3215 |
+
*/
|
3216 |
+
public function currency_is_accepted( $currency = null ) {
|
3217 |
+
|
3218 |
+
// accept all currencies
|
3219 |
+
if ( ! $this->currencies ) {
|
3220 |
+
return true;
|
3221 |
+
}
|
3222 |
+
|
3223 |
+
// default to order/WC currency
|
3224 |
+
if ( is_null( $currency ) ) {
|
3225 |
+
$currency = $this->get_payment_currency();
|
3226 |
+
}
|
3227 |
+
|
3228 |
+
return in_array( $currency, $this->currencies, true );
|
3229 |
+
}
|
3230 |
+
|
3231 |
+
/**
|
3232 |
+
* Adds order meta data.
|
3233 |
+
*
|
3234 |
+
* @since 3.0.0
|
3235 |
+
*
|
3236 |
+
* @param \WC_Order|int the order to add meta to
|
3237 |
+
* @param string $key meta key (already prefixed with gateway ID)
|
3238 |
+
* @param mixed $value meta value
|
3239 |
+
* @param bool $unique whether the meta value should be unique
|
3240 |
+
* @return false|void
|
3241 |
+
*/
|
3242 |
+
public function add_order_meta( $order, $key, $value, $unique = false ) {
|
3243 |
+
|
3244 |
+
if ( is_numeric( $order ) ) {
|
3245 |
+
$order = wc_get_order( $order );
|
3246 |
+
}
|
3247 |
+
|
3248 |
+
if ( ! $order instanceof \WC_Order ) {
|
3249 |
+
return false;
|
3250 |
+
}
|
3251 |
+
|
3252 |
+
return Order_Compatibility::add_meta_data( $order, $this->get_order_meta_prefix() . $key, $value, $unique );
|
3253 |
+
}
|
3254 |
+
|
3255 |
+
|
3256 |
+
/**
|
3257 |
+
* Gets order meta data.
|
3258 |
+
*
|
3259 |
+
* Note this is hardcoded to return a single value for the get_post_meta() call.
|
3260 |
+
*
|
3261 |
+
* @since 3.0.0
|
3262 |
+
* @param \WC_Order|int the order to get meta for
|
3263 |
+
* @param string $key meta key
|
3264 |
+
* @return mixed
|
3265 |
+
*/
|
3266 |
+
public function get_order_meta( $order, $key ) {
|
3267 |
+
|
3268 |
+
if ( is_numeric( $order ) ) {
|
3269 |
+
$order = wc_get_order( $order );
|
3270 |
+
}
|
3271 |
+
|
3272 |
+
if ( ! $order instanceof \WC_Order ) {
|
3273 |
+
return false;
|
3274 |
+
}
|
3275 |
+
|
3276 |
+
return Order_Compatibility::get_meta( $order, $this->get_order_meta_prefix() . $key, true );
|
3277 |
+
}
|
3278 |
+
|
3279 |
+
|
3280 |
+
/**
|
3281 |
+
* Updates order meta data.
|
3282 |
+
*
|
3283 |
+
* @since 3.0.0
|
3284 |
+
*
|
3285 |
+
* @param \WC_Order|int the order to update meta for
|
3286 |
+
* @param string $key meta key
|
3287 |
+
* @param mixed $value meta value
|
3288 |
+
* @return false|void
|
3289 |
+
*/
|
3290 |
+
public function update_order_meta( $order, $key, $value ) {
|
3291 |
+
|
3292 |
+
if ( is_numeric( $order ) ) {
|
3293 |
+
$order = wc_get_order( $order );
|
3294 |
+
}
|
3295 |
+
|
3296 |
+
if ( ! $order instanceof \WC_Order ) {
|
3297 |
+
return false;
|
3298 |
+
}
|
3299 |
+
|
3300 |
+
return Order_Compatibility::update_meta_data( $order, $this->get_order_meta_prefix() . $key, $value );
|
3301 |
+
}
|
3302 |
+
|
3303 |
+
|
3304 |
+
/**
|
3305 |
+
* Delete order meta data.
|
3306 |
+
*
|
3307 |
+
* @since 3.0.0
|
3308 |
+
* @param \WC_Order|int the order to delete meta for
|
3309 |
+
* @param string $key meta key
|
3310 |
+
* @return bool
|
3311 |
+
*/
|
3312 |
+
public function delete_order_meta( $order, $key ) {
|
3313 |
+
|
3314 |
+
if ( is_numeric( $order ) ) {
|
3315 |
+
$order = wc_get_order( $order );
|
3316 |
+
}
|
3317 |
+
|
3318 |
+
if ( ! $order instanceof \WC_Order ) {
|
3319 |
+
return false;
|
3320 |
+
}
|
3321 |
+
|
3322 |
+
return Order_Compatibility::delete_meta_data( $order, $this->get_order_meta_prefix() . $key );
|
3323 |
+
}
|
3324 |
+
|
3325 |
+
|
3326 |
+
/**
|
3327 |
+
* Gets the order meta prefixed used for the *_order_meta() methods
|
3328 |
+
*
|
3329 |
+
* Defaults to `_wc_{gateway_id}_`
|
3330 |
+
*
|
3331 |
+
* @since 3.0.0
|
3332 |
+
* @return string
|
3333 |
+
*/
|
3334 |
+
public function get_order_meta_prefix() {
|
3335 |
+
return '_wc_' . $this->get_id() . '_';
|
3336 |
+
}
|
3337 |
+
|
3338 |
+
/**
|
3339 |
+
* Returns the payment gateway id
|
3340 |
+
*
|
3341 |
+
* @since 3.0.0
|
3342 |
+
* @see WC_Payment_Gateway::$id
|
3343 |
+
* @return string payment gateway id
|
3344 |
+
*/
|
3345 |
+
public function get_id() {
|
3346 |
+
return $this->id;
|
3347 |
+
}
|
3348 |
+
|
3349 |
+
/**
|
3350 |
+
* Returns the payment gateway id with dashes in place of underscores, and
|
3351 |
+
* appropriate for use in frontend element names, classes and ids
|
3352 |
+
*
|
3353 |
+
* @since 3.0.0
|
3354 |
+
* @return string payment gateway id with dashes in place of underscores
|
3355 |
+
*/
|
3356 |
+
public function get_id_dasherized() {
|
3357 |
+
return str_replace( '_', '-', $this->get_id() );
|
3358 |
+
}
|
3359 |
+
|
3360 |
+
|
3361 |
+
/**
|
3362 |
+
* Returns the parent plugin object
|
3363 |
+
*
|
3364 |
+
* @since 3.0.0
|
3365 |
+
*
|
3366 |
+
* @return Payment_Gateway_Plugin the parent plugin object
|
3367 |
+
*/
|
3368 |
+
public function get_plugin() {
|
3369 |
+
|
3370 |
+
return $this->plugin;
|
3371 |
+
}
|
3372 |
+
|
3373 |
+
|
3374 |
+
/**
|
3375 |
+
* Returns the admin method title. This should be the gateway name, ie
|
3376 |
+
* 'Intuit QBMS'
|
3377 |
+
*
|
3378 |
+
* @since 3.0.0
|
3379 |
+
* @see WC_Settings_API::$method_title
|
3380 |
+
* @return string method title
|
3381 |
+
*/
|
3382 |
+
public function get_method_title() {
|
3383 |
+
return $this->method_title;
|
3384 |
+
}
|
3385 |
+
|
3386 |
+
|
3387 |
+
/**
|
3388 |
+
* Determines if the Card Security Code (CVV) field should be used at checkout.
|
3389 |
+
*
|
3390 |
+
* @since 3.0.0
|
3391 |
+
* @return bool
|
3392 |
+
*/
|
3393 |
+
public function csc_enabled() {
|
3394 |
+
return 'yes' === $this->enable_csc;
|
3395 |
+
}
|
3396 |
+
|
3397 |
+
|
3398 |
+
/**
|
3399 |
+
* Determines if the Card Security Code (CVV) field should be used for saved cards at checkout.
|
3400 |
+
*
|
3401 |
+
* @since 3.0.0
|
3402 |
+
* @return bool
|
3403 |
+
*/
|
3404 |
+
public function csc_enabled_for_tokens() {
|
3405 |
+
return $this->csc_enabled() && 'yes' === $this->enable_token_csc;
|
3406 |
+
}
|
3407 |
+
|
3408 |
+
|
3409 |
+
/**
|
3410 |
+
* Determines if the Card Security Code (CVV) field should be required at checkout.
|
3411 |
+
*
|
3412 |
+
* @since 3.0.0
|
3413 |
+
* @return bool
|
3414 |
+
*/
|
3415 |
+
public function csc_required() {
|
3416 |
+
return $this->csc_enabled();
|
3417 |
+
}
|
3418 |
+
|
3419 |
+
|
3420 |
+
/**
|
3421 |
+
* Determines if the gateway supports sharing settings with sibling gateways.
|
3422 |
+
*
|
3423 |
+
* @since 3.0.0
|
3424 |
+
* @return bool
|
3425 |
+
*/
|
3426 |
+
public function share_settings() {
|
3427 |
+
return true;
|
3428 |
+
}
|
3429 |
+
|
3430 |
+
|
3431 |
+
/**
|
3432 |
+
* Determines if settings should be inherited for this gateway.
|
3433 |
+
*
|
3434 |
+
* @since 3.0.0
|
3435 |
+
* @return bool
|
3436 |
+
*/
|
3437 |
+
public function inherit_settings() {
|
3438 |
+
return 'yes' === $this->inherit_settings;
|
3439 |
+
}
|
3440 |
+
|
3441 |
+
/**
|
3442 |
+
* Returns an array of two-letter country codes this gateway is allowed for, defaults to all
|
3443 |
+
*
|
3444 |
+
* @since 3.0.0
|
3445 |
+
* @see WC_Payment_Gateway::$countries
|
3446 |
+
* @return array of two-letter country codes this gateway is allowed for, defaults to all
|
3447 |
+
*/
|
3448 |
+
public function get_available_countries() {
|
3449 |
+
return $this->countries;
|
3450 |
+
}
|
3451 |
+
|
3452 |
+
/**
|
3453 |
+
* Add support for the named feature or features
|
3454 |
+
*
|
3455 |
+
* @since 3.0.0
|
3456 |
+
* @param string|array $feature the feature name or names supported by this gateway
|
3457 |
+
*/
|
3458 |
+
public function add_support( $feature ) {
|
3459 |
+
|
3460 |
+
if ( ! is_array( $feature ) ) {
|
3461 |
+
$feature = array( $feature );
|
3462 |
+
}
|
3463 |
+
|
3464 |
+
foreach ( $feature as $name ) {
|
3465 |
+
|
3466 |
+
// add support for feature if it's not already declared
|
3467 |
+
if ( ! in_array( $name, $this->supports, true ) ) {
|
3468 |
+
|
3469 |
+
$this->supports[] = $name;
|
3470 |
+
|
3471 |
+
/**
|
3472 |
+
* Payment Gateway Add Support Action.
|
3473 |
+
*
|
3474 |
+
* Fired when declaring support for a specific gateway feature. Allows other actors
|
3475 |
+
* (including ourselves) to take action when support is declared.
|
3476 |
+
*
|
3477 |
+
* @since 3.0.0
|
3478 |
+
*
|
3479 |
+
* @param Payment_Gateway $this instance
|
3480 |
+
* @param string $name of supported feature being added
|
3481 |
+
*/
|
3482 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_supports_' . str_replace( '-', '_', $name ), $this, $name );
|
3483 |
+
}
|
3484 |
+
|
3485 |
+
}
|
3486 |
+
}
|
3487 |
+
|
3488 |
+
/**
|
3489 |
+
* Set all features supported
|
3490 |
+
*
|
3491 |
+
* @since 3.0.0
|
3492 |
+
* @param array $features array of supported feature names
|
3493 |
+
*/
|
3494 |
+
public function set_supports( $features ) {
|
3495 |
+
$this->supports = $features;
|
3496 |
+
}
|
3497 |
+
|
3498 |
+
/**
|
3499 |
+
* Gets the set of environments supported by this gateway. All gateways
|
3500 |
+
* support at least the production environment
|
3501 |
+
*
|
3502 |
+
* @since 3.0.0
|
3503 |
+
* @return array associative array of environment id to name supported by this gateway
|
3504 |
+
*/
|
3505 |
+
public function get_environments() {
|
3506 |
+
|
3507 |
+
// default set of environments consists of 'production'
|
3508 |
+
if ( ! isset( $this->environments ) ) {
|
3509 |
+
$this->environments = array( self::ENVIRONMENT_PRODUCTION => esc_html_x( 'Production', 'software environment', 'woocommerce-square' ) );
|
3510 |
+
}
|
3511 |
+
|
3512 |
+
return $this->environments;
|
3513 |
+
}
|
3514 |
+
|
3515 |
+
|
3516 |
+
/**
|
3517 |
+
* Returns the environment setting, one of the $environments keys, ie
|
3518 |
+
* 'production'
|
3519 |
+
*
|
3520 |
+
* @since 3.0.0
|
3521 |
+
* @return string the configured environment id
|
3522 |
+
*/
|
3523 |
+
public function get_environment() {
|
3524 |
+
return $this->environment;
|
3525 |
+
}
|
3526 |
+
|
3527 |
+
|
3528 |
+
/**
|
3529 |
+
* Get the configured environment's display name.
|
3530 |
+
*
|
3531 |
+
* @since 3.0.0
|
3532 |
+
* @return string The configured environment name
|
3533 |
+
*/
|
3534 |
+
public function get_environment_name() {
|
3535 |
+
|
3536 |
+
$environments = $this->get_environments();
|
3537 |
+
|
3538 |
+
$environment_id = $this->get_environment();
|
3539 |
+
$environment_name = ( isset( $environments[ $environment_id ] ) ) ? $environments[ $environment_id ] : $environment_id;
|
3540 |
+
|
3541 |
+
return $environment_name;
|
3542 |
+
}
|
3543 |
+
|
3544 |
+
|
3545 |
+
/**
|
3546 |
+
* Returns true if the current environment is $environment_id.
|
3547 |
+
*
|
3548 |
+
* @since 3.0.0
|
3549 |
+
*
|
3550 |
+
* @param string|mixed $environment_id
|
3551 |
+
* @return bool
|
3552 |
+
*/
|
3553 |
+
public function is_environment( $environment_id ) {
|
3554 |
+
return $environment_id == $this->get_environment();
|
3555 |
+
}
|
3556 |
+
|
3557 |
+
|
3558 |
+
/**
|
3559 |
+
* Returns true if the current gateway environment is configured to
|
3560 |
+
* 'production'. All gateways have at least the production environment
|
3561 |
+
*
|
3562 |
+
* @since 3.0.0
|
3563 |
+
* @param string $environment_id optional environment id to check, otherwise defaults to the gateway current environment
|
3564 |
+
* @return boolean true if $environment_id (if non-null) or otherwise the current environment is production
|
3565 |
+
*/
|
3566 |
+
public function is_production_environment( $environment_id = null ) {
|
3567 |
+
|
3568 |
+
// if an environment was passed in, see whether it's the production environment
|
3569 |
+
if ( ! is_null( $environment_id ) ) {
|
3570 |
+
return self::ENVIRONMENT_PRODUCTION == $environment_id;
|
3571 |
+
}
|
3572 |
+
|
3573 |
+
// default: check the current environment
|
3574 |
+
return $this->is_environment( self::ENVIRONMENT_PRODUCTION );
|
3575 |
+
}
|
3576 |
+
|
3577 |
+
|
3578 |
+
/**
|
3579 |
+
* Returns true if the current gateway environment is configured to 'test'
|
3580 |
+
*
|
3581 |
+
* @since 3.0.0
|
3582 |
+
* @param string $environment_id optional environment id to check, otherwise defaults to the gateway current environment
|
3583 |
+
* @return boolean true if $environment_id (if non-null) or otherwise the current environment is test
|
3584 |
+
*/
|
3585 |
+
public function is_test_environment( $environment_id = null ) {
|
3586 |
+
|
3587 |
+
// if an environment was passed in, see whether it's the production environment
|
3588 |
+
if ( ! is_null( $environment_id ) ) {
|
3589 |
+
return self::ENVIRONMENT_TEST == $environment_id;
|
3590 |
+
}
|
3591 |
+
|
3592 |
+
// default: check the current environment
|
3593 |
+
return $this->is_environment( self::ENVIRONMENT_TEST );
|
3594 |
+
}
|
3595 |
+
|
3596 |
+
|
3597 |
+
/**
|
3598 |
+
* Returns true if the gateway is enabled. This has nothing to do with
|
3599 |
+
* whether the gateway is properly configured or functional.
|
3600 |
+
*
|
3601 |
+
* @since 3.0.0
|
3602 |
+
* @see WC_Payment_Gateway::$enabled
|
3603 |
+
* @return boolean true if the gateway is enabled
|
3604 |
+
*/
|
3605 |
+
public function is_enabled() {
|
3606 |
+
return 'yes' == $this->enabled;
|
3607 |
+
}
|
3608 |
+
|
3609 |
+
|
3610 |
+
/**
|
3611 |
+
* Returns true if detailed decline messages should be displayed to
|
3612 |
+
* customers on checkout when available, rather than a single generic
|
3613 |
+
* decline message
|
3614 |
+
*
|
3615 |
+
* @since 3.0.0
|
3616 |
+
* @see Payment_Gateway_API_Response_Message_Helper
|
3617 |
+
* @see Payment_Gateway_API_Response::get_user_message()
|
3618 |
+
* @return boolean true if detailed decline messages should be displayed
|
3619 |
+
* on checkout
|
3620 |
+
*/
|
3621 |
+
public function is_detailed_customer_decline_messages_enabled() {
|
3622 |
+
return 'yes' == $this->enable_customer_decline_messages;
|
3623 |
+
}
|
3624 |
+
|
3625 |
+
|
3626 |
+
/**
|
3627 |
+
* Returns the set of accepted currencies, or empty array if all currencies
|
3628 |
+
* are accepted by this gateway
|
3629 |
+
*
|
3630 |
+
* @since 3.0.0
|
3631 |
+
* @return array of currencies accepted by this gateway
|
3632 |
+
*/
|
3633 |
+
public function get_accepted_currencies() {
|
3634 |
+
return $this->currencies;
|
3635 |
+
}
|
3636 |
+
|
3637 |
+
|
3638 |
+
/**
|
3639 |
+
* Returns true if all debugging is disabled
|
3640 |
+
*
|
3641 |
+
* @since 3.0.0
|
3642 |
+
* @return boolean if all debuging is disabled
|
3643 |
+
*/
|
3644 |
+
public function debug_off() {
|
3645 |
+
return self::DEBUG_MODE_OFF === $this->debug_mode;
|
3646 |
+
}
|
3647 |
+
|
3648 |
+
|
3649 |
+
/**
|
3650 |
+
* Returns true if debug logging is enabled
|
3651 |
+
*
|
3652 |
+
* @since 3.0.0
|
3653 |
+
* @return boolean if debug logging is enabled
|
3654 |
+
*/
|
3655 |
+
public function debug_log() {
|
3656 |
+
return self::DEBUG_MODE_LOG === $this->debug_mode || self::DEBUG_MODE_BOTH === $this->debug_mode;
|
3657 |
+
}
|
3658 |
+
|
3659 |
+
|
3660 |
+
/**
|
3661 |
+
* Returns true if checkout debugging is enabled. This will cause debugging
|
3662 |
+
* statements to be displayed on the checkout/pay pages
|
3663 |
+
*
|
3664 |
+
* @since 3.0.0
|
3665 |
+
* @return boolean if checkout debugging is enabled
|
3666 |
+
*/
|
3667 |
+
public function debug_checkout() {
|
3668 |
+
return self::DEBUG_MODE_CHECKOUT === $this->debug_mode || self::DEBUG_MODE_BOTH === $this->debug_mode;
|
3669 |
+
}
|
3670 |
+
|
3671 |
+
|
3672 |
+
/**
|
3673 |
+
* Returns true if this is a direct type gateway
|
3674 |
+
*
|
3675 |
+
* @since 3.0.0
|
3676 |
+
* @return boolean if this is a direct payment gateway
|
3677 |
+
*/
|
3678 |
+
public function is_direct_gateway() {
|
3679 |
+
return false;
|
3680 |
+
}
|
3681 |
+
|
3682 |
+
|
3683 |
+
/**
|
3684 |
+
* Returns true if this is a hosted type gateway
|
3685 |
+
*
|
3686 |
+
* @since 3.0.0
|
3687 |
+
* @return boolean if this is a hosted IPN payment gateway
|
3688 |
+
*/
|
3689 |
+
public function is_hosted_gateway() {
|
3690 |
+
return false;
|
3691 |
+
}
|
3692 |
+
|
3693 |
+
|
3694 |
+
/**
|
3695 |
+
* Returns the payment type for this gateway
|
3696 |
+
*
|
3697 |
+
* @since 3.0.0
|
3698 |
+
* @return string the payment type, ie 'credit-card'.
|
3699 |
+
*/
|
3700 |
+
public function get_payment_type() {
|
3701 |
+
return $this->payment_type;
|
3702 |
+
}
|
3703 |
+
|
3704 |
+
|
3705 |
+
/**
|
3706 |
+
* Returns true if this is a credit card gateway
|
3707 |
+
*
|
3708 |
+
* @since 3.0.0
|
3709 |
+
* @return boolean true if this is a credit card gateway
|
3710 |
+
*/
|
3711 |
+
public function is_credit_card_gateway() {
|
3712 |
+
return self::PAYMENT_TYPE_CREDIT_CARD == $this->get_payment_type();
|
3713 |
+
}
|
3714 |
+
|
3715 |
+
/**
|
3716 |
+
* Returns the API instance for this gateway if it uses direct communication
|
3717 |
+
*
|
3718 |
+
* This is a stub method which must be overridden if this gateway performs
|
3719 |
+
* direct communication
|
3720 |
+
*
|
3721 |
+
* @since 3.0.0
|
3722 |
+
* @return SquareFramework\PaymentGateway\Api\Payment_Gateway_API the payment gateway API instance
|
3723 |
+
*/
|
3724 |
+
public function get_api() {
|
3725 |
+
|
3726 |
+
// concrete stub method
|
3727 |
+
assert( false );
|
3728 |
+
}
|
3729 |
+
|
3730 |
+
|
3731 |
+
/**
|
3732 |
+
* Returns the order_id if on the checkout pay page
|
3733 |
+
*
|
3734 |
+
* @since 3.0.0
|
3735 |
+
* @return int order identifier
|
3736 |
+
*/
|
3737 |
+
public function get_checkout_pay_page_order_id() {
|
3738 |
+
global $wp;
|
3739 |
+
|
3740 |
+
return isset( $wp->query_vars['order-pay'] ) ? absint( $wp->query_vars['order-pay'] ) : 0;
|
3741 |
+
}
|
3742 |
+
|
3743 |
+
/**
|
3744 |
+
* Gets the maximum amount that can be captured from an order.
|
3745 |
+
*
|
3746 |
+
* Gateways can override this for an value above or below the order total.
|
3747 |
+
* For instance, some processors allow capturing an amount a certain
|
3748 |
+
* percentage higher than the payment total.
|
3749 |
+
*
|
3750 |
+
* @since 3.0.0
|
3751 |
+
*
|
3752 |
+
* @param \WC_Order $order order object
|
3753 |
+
* @return float
|
3754 |
+
*/
|
3755 |
+
public function get_order_capture_maximum( \WC_Order $order ) {
|
3756 |
+
|
3757 |
+
wc_deprecated_function( __METHOD__, '3.0.0', get_class( $this->get_capture_handler() ) . '::get_order_capture_maximum()' );
|
3758 |
+
|
3759 |
+
return $this->get_capture_handler()->get_order_capture_maximum( $order );
|
3760 |
+
}
|
3761 |
+
|
3762 |
+
|
3763 |
+
/**
|
3764 |
+
* Gets the amount originally authorized for an order.
|
3765 |
+
*
|
3766 |
+
* @since 3.0.0
|
3767 |
+
*
|
3768 |
+
* @param \WC_Order $order order object
|
3769 |
+
* @return float
|
3770 |
+
*/
|
3771 |
+
public function get_order_authorization_amount( \WC_Order $order ) {
|
3772 |
+
|
3773 |
+
wc_deprecated_function( __METHOD__, '3.0.0', get_class( $this->get_capture_handler() ) . '::get_order_authorization_amount()' );
|
3774 |
+
|
3775 |
+
return $this->get_capture_handler()->get_order_authorization_amount( $order );
|
3776 |
+
}
|
3777 |
+
|
3778 |
+
/**
|
3779 |
+
* Returns the gateway icon markup
|
3780 |
+
*
|
3781 |
+
* @since 3.0.0
|
3782 |
+
* @see WC_Payment_Gateway::get_icon()
|
3783 |
+
* @return string icon markup
|
3784 |
+
*/
|
3785 |
+
public function get_icon() {
|
3786 |
+
|
3787 |
+
$icon = '';
|
3788 |
+
|
3789 |
+
// specific icon
|
3790 |
+
if ( $this->icon ) {
|
3791 |
+
|
3792 |
+
// use icon provided by filter
|
3793 |
+
$icon = sprintf( '<img src="%s" alt="%s" class="sv-wc-payment-gateway-icon wc-%s-payment-gateway-icon" />', esc_url( \WC_HTTPS::force_https_url( $this->icon ) ), esc_attr( $this->get_title() ), esc_attr( $this->get_id_dasherized() ) );
|
3794 |
+
}
|
3795 |
+
|
3796 |
+
// credit card images
|
3797 |
+
if ( ! $icon && $this->supports_card_types() && $this->get_card_types() ) {
|
3798 |
+
|
3799 |
+
// display icons for the selected card types
|
3800 |
+
foreach ( $this->get_card_types() as $card_type ) {
|
3801 |
+
|
3802 |
+
$card_type = Payment_Gateway_Helper::normalize_card_type( $card_type );
|
3803 |
+
|
3804 |
+
if ( $url = $this->get_payment_method_image_url( $card_type ) ) {
|
3805 |
+
$icon .= sprintf( '<img src="%s" alt="%s" class="sv-wc-payment-gateway-icon wc-%s-payment-gateway-icon" width="40" height="25" style="width: 40px; height: 25px;" />', esc_url( $url ), esc_attr( $card_type ), esc_attr( $this->get_id_dasherized() ) );
|
3806 |
+
}
|
3807 |
+
}
|
3808 |
+
}
|
3809 |
+
|
3810 |
+
/* This filter is documented in WC core */
|
3811 |
+
return apply_filters( 'woocommerce_gateway_icon', $icon, $this->get_id() );
|
3812 |
+
}
|
3813 |
+
}
|
includes/Framework/PaymentGateway/Payment_Gateway_Direct.php
ADDED
@@ -0,0 +1,1007 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway;
|
4 |
+
|
5 |
+
use WooCommerce;
|
6 |
+
use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
|
7 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
8 |
+
use WooCommerce\Square\Framework\Compatibility\Order_Compatibility;
|
9 |
+
use WooCommerce\Square\Framework\Addresses\Customer_Address;
|
10 |
+
use WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Response_Interface;
|
11 |
+
|
12 |
+
defined( 'ABSPATH' ) or exit;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* # WooCommerce Payment Gateway Framework Direct Gateway
|
16 |
+
*
|
17 |
+
* @since 3.0.0
|
18 |
+
*/
|
19 |
+
abstract class Payment_Gateway_Direct extends Payment_Gateway {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Validate the payment fields when processing the checkout
|
23 |
+
*
|
24 |
+
* NOTE: if we want to bring billing field validation (ie length) into the
|
25 |
+
* fold, see the Elavon VM Payment Gateway for a sample implementation
|
26 |
+
*
|
27 |
+
* @since 3.0.0
|
28 |
+
* @see WC_Payment_Gateway::validate_fields()
|
29 |
+
* @return bool true if fields are valid, false otherwise
|
30 |
+
*/
|
31 |
+
public function validate_fields() {
|
32 |
+
|
33 |
+
$is_valid = parent::validate_fields();
|
34 |
+
|
35 |
+
if ( $this->supports_tokenization() ) {
|
36 |
+
|
37 |
+
// tokenized transaction?
|
38 |
+
if ( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-token' ) ) {
|
39 |
+
|
40 |
+
// unknown token?
|
41 |
+
if ( ! $this->get_payment_tokens_handler()->user_has_token( get_current_user_id(), Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-token' ) ) ) {
|
42 |
+
Square_Helper::wc_add_notice( esc_html__( 'Payment error, please try another payment method or contact us to complete your transaction.', 'woocommerce-square' ), 'error' );
|
43 |
+
$is_valid = false;
|
44 |
+
}
|
45 |
+
|
46 |
+
// Check the CSC if enabled
|
47 |
+
if ( $this->is_credit_card_gateway() && $this->csc_enabled_for_tokens() ) {
|
48 |
+
$is_valid = $this->validate_csc( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-csc' ) ) && $is_valid;
|
49 |
+
}
|
50 |
+
|
51 |
+
// no more validation to perform
|
52 |
+
return $is_valid;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
// validate remaining payment fields
|
57 |
+
if ( $this->is_credit_card_gateway() ) {
|
58 |
+
return $this->validate_credit_card_fields( $is_valid );
|
59 |
+
} else {
|
60 |
+
$method_name = 'validate_' . str_replace( '-', '_', strtolower( $this->get_payment_type() ) ) . '_fields';
|
61 |
+
if ( is_callable( array( $this, $method_name ) ) ) {
|
62 |
+
return $this->$method_name( $is_valid );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
// no more validation to perform. Return the parent method's outcome.
|
67 |
+
return $is_valid;
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns true if the posted credit card fields are valid, false otherwise
|
73 |
+
*
|
74 |
+
* @since 3.0.0
|
75 |
+
* @param boolean $is_valid true if the fields are valid, false otherwise
|
76 |
+
* @return boolean true if the fields are valid, false otherwise
|
77 |
+
*/
|
78 |
+
protected function validate_credit_card_fields( $is_valid ) {
|
79 |
+
|
80 |
+
$account_number = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-account-number' );
|
81 |
+
$expiration_month = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-month' );
|
82 |
+
$expiration_year = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-year' );
|
83 |
+
$expiry = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-expiry' );
|
84 |
+
$csc = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-csc' );
|
85 |
+
|
86 |
+
// handle single expiry field formatted like "MM / YY" or "MM / YYYY"
|
87 |
+
if ( ! $expiration_month & ! $expiration_year && $expiry ) {
|
88 |
+
list( $expiration_month, $expiration_year ) = array_map( 'trim', explode( '/', $expiry ) );
|
89 |
+
}
|
90 |
+
|
91 |
+
$is_valid = $this->validate_credit_card_account_number( $account_number ) && $is_valid;
|
92 |
+
|
93 |
+
$is_valid = $this->validate_credit_card_expiration_date( $expiration_month, $expiration_year ) && $is_valid;
|
94 |
+
|
95 |
+
// validate card security code
|
96 |
+
if ( $this->csc_enabled() ) {
|
97 |
+
$is_valid = $this->validate_csc( $csc ) && $is_valid;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Direct Payment Gateway Validate Credit Card Fields Filter.
|
102 |
+
*
|
103 |
+
* Allow actors to filter the credit card field validation.
|
104 |
+
*
|
105 |
+
* @since 3.0.0
|
106 |
+
* @param bool $is_valid true for validation to pass
|
107 |
+
* @param Payment_Gateway_Direct $this direct gateway class instance
|
108 |
+
*/
|
109 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_validate_credit_card_fields', $is_valid, $this );
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Validates the provided credit card expiration date
|
115 |
+
*
|
116 |
+
* @since 3.0.0
|
117 |
+
* @param string $expiration_month the credit card expiration month
|
118 |
+
* @param string $expiration_year the credit card expiration month
|
119 |
+
* @return boolean true if the card expiration date is valid, false otherwise
|
120 |
+
*/
|
121 |
+
protected function validate_credit_card_expiration_date( $expiration_month, $expiration_year ) {
|
122 |
+
|
123 |
+
$is_valid = true;
|
124 |
+
|
125 |
+
if ( 2 === strlen( $expiration_year ) ) {
|
126 |
+
$expiration_year = '20' . $expiration_year;
|
127 |
+
}
|
128 |
+
|
129 |
+
// validate expiration data
|
130 |
+
$current_year = date( 'Y' );
|
131 |
+
$current_month = date( 'n' );
|
132 |
+
|
133 |
+
if ( ! ctype_digit( $expiration_month ) || ! ctype_digit( $expiration_year ) ||
|
134 |
+
$expiration_month > 12 ||
|
135 |
+
$expiration_month < 1 ||
|
136 |
+
$expiration_year < $current_year ||
|
137 |
+
( $expiration_year == $current_year && $expiration_month < $current_month ) ||
|
138 |
+
$expiration_year > $current_year + 20
|
139 |
+
) {
|
140 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card expiration date is invalid', 'woocommerce-square' ), 'error' );
|
141 |
+
$is_valid = false;
|
142 |
+
}
|
143 |
+
|
144 |
+
return $is_valid;
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Validates the provided credit card account number
|
150 |
+
*
|
151 |
+
* @since 3.0.0
|
152 |
+
* @param string $account_number the credit card account number
|
153 |
+
* @return boolean true if the card account number is valid, false otherwise
|
154 |
+
*/
|
155 |
+
protected function validate_credit_card_account_number( $account_number ) {
|
156 |
+
|
157 |
+
$is_valid = true;
|
158 |
+
|
159 |
+
// validate card number
|
160 |
+
$account_number = str_replace( array( ' ', '-' ), '', $account_number );
|
161 |
+
|
162 |
+
if ( empty( $account_number ) ) {
|
163 |
+
|
164 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card number is missing', 'woocommerce-square' ), 'error' );
|
165 |
+
$is_valid = false;
|
166 |
+
|
167 |
+
} else {
|
168 |
+
|
169 |
+
if ( strlen( $account_number ) < 12 || strlen( $account_number ) > 19 ) {
|
170 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card number is invalid (wrong length)', 'woocommerce-square' ), 'error' );
|
171 |
+
$is_valid = false;
|
172 |
+
}
|
173 |
+
|
174 |
+
if ( ! ctype_digit( $account_number ) ) {
|
175 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card number is invalid (only digits allowed)', 'woocommerce-square' ), 'error' );
|
176 |
+
$is_valid = false;
|
177 |
+
}
|
178 |
+
|
179 |
+
if ( ! Payment_Gateway_Helper::luhn_check( $account_number ) ) {
|
180 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card number is invalid', 'woocommerce-square' ), 'error' );
|
181 |
+
$is_valid = false;
|
182 |
+
}
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
return $is_valid;
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Validates the provided Card Security Code, adding user error messages as
|
192 |
+
* needed
|
193 |
+
*
|
194 |
+
* @since 3.0.0
|
195 |
+
* @param string $csc the customer-provided card security code
|
196 |
+
* @return boolean true if the card security code is valid, false otherwise
|
197 |
+
*/
|
198 |
+
protected function validate_csc( $csc ) {
|
199 |
+
|
200 |
+
$is_valid = true;
|
201 |
+
|
202 |
+
// validate security code
|
203 |
+
if ( ! empty( $csc ) ) {
|
204 |
+
|
205 |
+
// digit validation
|
206 |
+
if ( ! ctype_digit( $csc ) ) {
|
207 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card security code is invalid (only digits are allowed)', 'woocommerce-square' ), 'error' );
|
208 |
+
$is_valid = false;
|
209 |
+
}
|
210 |
+
|
211 |
+
// length validation
|
212 |
+
if ( strlen( $csc ) < 3 || strlen( $csc ) > 4 ) {
|
213 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card security code is invalid (must be 3 or 4 digits)', 'woocommerce-square' ), 'error' );
|
214 |
+
$is_valid = false;
|
215 |
+
}
|
216 |
+
|
217 |
+
} elseif ( $this->csc_required() ) {
|
218 |
+
|
219 |
+
Square_Helper::wc_add_notice( esc_html__( 'Card security code is missing', 'woocommerce-square' ), 'error' );
|
220 |
+
$is_valid = false;
|
221 |
+
}
|
222 |
+
|
223 |
+
return $is_valid;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Handles payment processing.
|
228 |
+
*
|
229 |
+
* @see WC_Payment_Gateway::process_payment()
|
230 |
+
*
|
231 |
+
* @since 3.0.0
|
232 |
+
*
|
233 |
+
* @param int|string $order_id
|
234 |
+
* @return array associative array with members 'result' and 'redirect'
|
235 |
+
*/
|
236 |
+
public function process_payment( $order_id ) {
|
237 |
+
|
238 |
+
$default = parent::process_payment( $order_id );
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Direct Gateway Process Payment Filter.
|
242 |
+
*
|
243 |
+
* Allow actors to intercept and implement the process_payment() call for
|
244 |
+
* this transaction. Return an array value from this filter will return it
|
245 |
+
* directly to the checkout processing code and skip this method entirely.
|
246 |
+
*
|
247 |
+
* @since 3.0.0
|
248 |
+
* @param bool $result default true
|
249 |
+
* @param int|string $order_id order ID for the payment
|
250 |
+
* @param Payment_Gateway_Direct $this instance
|
251 |
+
*/
|
252 |
+
if ( is_array( $result = apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_process_payment', true, $order_id, $this ) ) ) {
|
253 |
+
return $result;
|
254 |
+
}
|
255 |
+
|
256 |
+
// add payment information to order
|
257 |
+
$order = $this->get_order( $order_id );
|
258 |
+
|
259 |
+
try {
|
260 |
+
|
261 |
+
// handle creating or updating a payment method for registered customers if tokenization is enabled
|
262 |
+
if ( $this->supports_tokenization() && 0 !== (int) $order->get_user_id() ) {
|
263 |
+
|
264 |
+
// if already paying with an existing method, try and updated it locally and remotely
|
265 |
+
if ( ! empty( $order->payment->token ) ) {
|
266 |
+
|
267 |
+
$this->update_transaction_payment_method( $order );
|
268 |
+
|
269 |
+
// otherwise, create a new token if desired
|
270 |
+
} elseif ( $this->get_payment_tokens_handler()->should_tokenize() && ( '0.00' === $order->payment_total || $this->tokenize_before_sale() ) ) {
|
271 |
+
|
272 |
+
$order = $this->get_payment_tokens_handler()->create_token( $order );
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
// payment failures are handled internally by do_transaction()
|
277 |
+
// the order amount will be $0 if a WooCommerce Subscriptions free trial product is being processed
|
278 |
+
// note that customer id & payment token are saved to order when create_token() is called
|
279 |
+
if ( ( '0.00' === $order->payment_total && ! $this->transaction_forced() ) || $this->do_transaction( $order ) ) {
|
280 |
+
|
281 |
+
// add transaction data for zero-dollar "orders"
|
282 |
+
if ( '0.00' === $order->payment_total ) {
|
283 |
+
$this->add_transaction_data( $order );
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Filters the order status that's considered to be "held".
|
288 |
+
*
|
289 |
+
* @since 3.0.0
|
290 |
+
*
|
291 |
+
* @param string $status held order status
|
292 |
+
* @param \WC_Order $order order object
|
293 |
+
* @param Payment_Gateway_API_Response_Interface|null $response API response object, if any
|
294 |
+
*/
|
295 |
+
$held_order_status = apply_filters( 'wc_' . $this->get_id() . '_held_order_status', 'on-hold', $order, null );
|
296 |
+
|
297 |
+
if ( $order->has_status( $held_order_status ) ) {
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Although `wc_reduce_stock_levels` accepts $order, it's necessary to pass
|
301 |
+
* the order ID instead as `wc_reduce_stock_levels` reloads the order from the DB.
|
302 |
+
*
|
303 |
+
* Refer to the following PR link for more details:
|
304 |
+
* @see https://github.com/woocommerce/woocommerce-square/pull/728
|
305 |
+
*/
|
306 |
+
wc_reduce_stock_levels( $order->get_id() ); // reduce stock for held orders, but don't complete payment
|
307 |
+
} else {
|
308 |
+
$order->payment_complete(); // mark order as having received payment
|
309 |
+
}
|
310 |
+
|
311 |
+
// process_payment() can sometimes be called in an admin-context
|
312 |
+
if ( isset( WC()->cart ) ) {
|
313 |
+
WC()->cart->empty_cart();
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Payment Gateway Payment Processed Action.
|
318 |
+
*
|
319 |
+
* Fired when a payment is processed for an order.
|
320 |
+
*
|
321 |
+
* @since 3.0.0
|
322 |
+
* @param \WC_Order $order order object
|
323 |
+
* @param Payment_Gateway_Direct $this instance
|
324 |
+
*/
|
325 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_payment_processed', $order, $this );
|
326 |
+
|
327 |
+
return array(
|
328 |
+
'result' => 'success',
|
329 |
+
'redirect' => $this->get_return_url( $order ),
|
330 |
+
);
|
331 |
+
}
|
332 |
+
|
333 |
+
} catch ( \Exception $e ) {
|
334 |
+
|
335 |
+
$this->mark_order_as_failed( $order, $e->getMessage() );
|
336 |
+
|
337 |
+
return array(
|
338 |
+
'result' => 'failure',
|
339 |
+
'message' => $e->getMessage(),
|
340 |
+
);
|
341 |
+
}
|
342 |
+
|
343 |
+
return $default;
|
344 |
+
}
|
345 |
+
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Handles updating a user's payment method during payment.
|
349 |
+
*
|
350 |
+
* This allows us to check the billing address against the last used so we can determine if it needs an update.
|
351 |
+
*
|
352 |
+
* @since 3.0.0
|
353 |
+
*
|
354 |
+
* @param \WC_Order $order
|
355 |
+
* @return \WC_Order
|
356 |
+
*/
|
357 |
+
protected function update_transaction_payment_method( \WC_Order $order ) {
|
358 |
+
|
359 |
+
$token = $this->get_payment_tokens_handler()->get_token( $order->get_user_id(), $order->payment->token );
|
360 |
+
$address = new Customer_Address();
|
361 |
+
$address->set_from_order( $order );
|
362 |
+
|
363 |
+
$new_billing_hash = $address->get_hash();
|
364 |
+
|
365 |
+
// if the address & token hash don't match, update
|
366 |
+
if ( $token->get_billing_hash() !== $new_billing_hash ) {
|
367 |
+
|
368 |
+
// if the API supports it, update remotely
|
369 |
+
if ( $this->get_api()->supports_update_tokenized_payment_method() ) {
|
370 |
+
|
371 |
+
$response = null;
|
372 |
+
|
373 |
+
try {
|
374 |
+
|
375 |
+
$response = $this->get_api()->update_tokenized_payment_method( $order );
|
376 |
+
|
377 |
+
// if an address was passed and the token was updated remotely, update the billing hash
|
378 |
+
if ( $response->transaction_approved() ) {
|
379 |
+
|
380 |
+
$token->set_billing_hash( $new_billing_hash );
|
381 |
+
|
382 |
+
} else {
|
383 |
+
|
384 |
+
if ( $response->get_status_message() ) {
|
385 |
+
$message = $response->get_status_code() ? $response->get_status_code() . ' - ' . $response->get_status_message() : $response->get_status_message();
|
386 |
+
} else {
|
387 |
+
$message = __( 'Unknown error', 'woocommerce-square' );
|
388 |
+
}
|
389 |
+
|
390 |
+
throw new \Exception( $message );
|
391 |
+
}
|
392 |
+
|
393 |
+
} catch ( \Exception $exception ) {
|
394 |
+
|
395 |
+
$message = sprintf(
|
396 |
+
esc_html__( 'Payment method address could not be updated. %s', 'woocommerce-square' ),
|
397 |
+
$exception->getMessage()
|
398 |
+
);
|
399 |
+
|
400 |
+
$order->add_order_note( $message );
|
401 |
+
|
402 |
+
if ( $this->debug_log() ) {
|
403 |
+
$this->get_plugin()->log( $message, $this->get_id() );
|
404 |
+
}
|
405 |
+
}
|
406 |
+
|
407 |
+
} else {
|
408 |
+
|
409 |
+
// updating remotely isn't supported, so just update the hash locally
|
410 |
+
$token->set_billing_hash( $new_billing_hash );
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
// don't halt payment if this fails
|
415 |
+
$this->get_payment_tokens_handler()->update_token( $order->get_user_id(), $token );
|
416 |
+
|
417 |
+
return $order;
|
418 |
+
}
|
419 |
+
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Add payment and transaction information as class members of WC_Order
|
423 |
+
* instance. The standard information that can be added includes:
|
424 |
+
*
|
425 |
+
* $order->payment_total - the payment total
|
426 |
+
* $order->customer_id - optional payment gateway customer id (useful for tokenized payments for certain gateways, etc)
|
427 |
+
* $order->payment->account_number - the credit card or checking account number
|
428 |
+
* $order->payment->last_four - the last four digits of the account number
|
429 |
+
* $order->payment->card_type - the card type (e.g. visa) derived from the account number
|
430 |
+
* $order->payment->routing_number - account routing number (check transactions only)
|
431 |
+
* $order->payment->account_type - optional type of account one of 'checking' or 'savings' if type is 'check'
|
432 |
+
* $order->payment->card_type - optional card type, ie one of 'visa', etc
|
433 |
+
* $order->payment->exp_month - the 2 digit credit card expiration month (for credit card gateways), e.g. 07
|
434 |
+
* $order->payment->exp_year - the 2 digit credit card expiration year (for credit card gateways), e.g. 17
|
435 |
+
* $order->payment->csc - the card security code (for credit card gateways)
|
436 |
+
* $order->payment->check_number - optional check number (check transactions only)
|
437 |
+
* $order->payment->drivers_license_number - optional driver license number (check transactions only)
|
438 |
+
* $order->payment->drivers_license_state - optional driver license state code (check transactions only)
|
439 |
+
* $order->payment->token - payment token (for tokenized transactions)
|
440 |
+
*
|
441 |
+
* Note that not all gateways will necessarily pass or require all of the
|
442 |
+
* above. These represent the most common attributes used among a variety
|
443 |
+
* of gateways, it's up to the specific gateway implementation to make use
|
444 |
+
* of, or ignore them, or add custom ones by overridding this method.
|
445 |
+
*
|
446 |
+
* @since 3.0.0
|
447 |
+
* @see WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway::get_order()
|
448 |
+
* @param int|\WC_Order $order_id order ID being processed
|
449 |
+
* @return \WC_Order object with payment and transaction information attached
|
450 |
+
*/
|
451 |
+
public function get_order( $order_id ) {
|
452 |
+
|
453 |
+
$order = parent::get_order( $order_id );
|
454 |
+
|
455 |
+
// payment info
|
456 |
+
if ( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-account-number' ) && ! Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-token' ) ) {
|
457 |
+
|
458 |
+
// common attributes
|
459 |
+
$order->payment->account_number = str_replace( array( ' ', '-' ), '', Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-account-number' ) );
|
460 |
+
$order->payment->last_four = substr( $order->payment->account_number, -4 );
|
461 |
+
|
462 |
+
if ( $this->is_credit_card_gateway() ) {
|
463 |
+
|
464 |
+
// credit card specific attributes
|
465 |
+
$order->payment->card_type = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-card-type' );
|
466 |
+
$order->payment->exp_month = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-month' );
|
467 |
+
$order->payment->exp_year = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-year' );
|
468 |
+
|
469 |
+
// add card type for gateways that don't require it displayed at checkout
|
470 |
+
if ( empty( $order->payment->card_type ) ) {
|
471 |
+
$order->payment->card_type = Payment_Gateway_Helper::card_type_from_account_number( $order->payment->account_number );
|
472 |
+
}
|
473 |
+
|
474 |
+
// handle single expiry field formatted like "MM / YY" or "MM / YYYY"
|
475 |
+
if ( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-expiry' ) ) {
|
476 |
+
list( $order->payment->exp_month, $order->payment->exp_year ) = array_map( 'trim', explode( '/', Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-expiry' ) ) );
|
477 |
+
}
|
478 |
+
|
479 |
+
// add CSC if enabled
|
480 |
+
if ( $this->csc_enabled() ) {
|
481 |
+
$order->payment->csc = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-csc' );
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
} elseif ( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-token' ) ) {
|
486 |
+
|
487 |
+
// paying with tokenized payment method (we've already verified that this token exists in the validate_fields method)
|
488 |
+
$token = $this->get_payment_tokens_handler()->get_token( $order->get_user_id(), Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-token' ) );
|
489 |
+
|
490 |
+
$order->payment->token = $token->get_id();
|
491 |
+
$order->payment->account_number = $token->get_last_four();
|
492 |
+
$order->payment->last_four = $token->get_last_four();
|
493 |
+
|
494 |
+
if ( $this->is_credit_card_gateway() ) {
|
495 |
+
|
496 |
+
// credit card specific attributes
|
497 |
+
$order->payment->card_type = $token->get_card_type();
|
498 |
+
$order->payment->exp_month = $token->get_exp_month();
|
499 |
+
$order->payment->exp_year = $token->get_exp_year();
|
500 |
+
|
501 |
+
if ( $this->csc_enabled_for_tokens() ) {
|
502 |
+
$order->payment->csc = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-csc' );
|
503 |
+
}
|
504 |
+
}
|
505 |
+
// make this the new default payment token
|
506 |
+
$this->get_payment_tokens_handler()->set_default_token( $order->get_user_id(), $token );
|
507 |
+
}
|
508 |
+
|
509 |
+
// standardize expiration date year to 2 digits
|
510 |
+
if ( ! empty( $order->payment->exp_year ) && 4 === strlen( $order->payment->exp_year ) ) {
|
511 |
+
$order->payment->exp_year = substr( $order->payment->exp_year, 2 );
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Direct Gateway Get Order Filter.
|
516 |
+
*
|
517 |
+
* Allow actors to modify the order object.
|
518 |
+
*
|
519 |
+
* @since 3.0.0
|
520 |
+
* @param \WC_Order $order order object
|
521 |
+
* @param Payment_Gateway_Direct $this instance
|
522 |
+
*/
|
523 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_get_order', $order, $this );
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Performs a credit card transaction for the given order and returns the result.
|
528 |
+
*
|
529 |
+
* @since 3.0.0
|
530 |
+
*
|
531 |
+
* @param \WC_Order $order the order object
|
532 |
+
* @param Payment_Gateway_API_Response_Interface $response optional credit card transaction response
|
533 |
+
* @return Payment_Gateway_API_Response_Interface the response
|
534 |
+
* @throws \Exception network timeouts, etc
|
535 |
+
*/
|
536 |
+
protected function do_credit_card_transaction( $order, $response = null ) {
|
537 |
+
|
538 |
+
if ( is_null( $response ) ) {
|
539 |
+
if ( $this->perform_credit_card_charge( $order ) ) {
|
540 |
+
$response = $this->get_api()->credit_card_charge( $order );
|
541 |
+
} else {
|
542 |
+
$response = $this->get_api()->credit_card_authorization( $order );
|
543 |
+
}
|
544 |
+
}
|
545 |
+
|
546 |
+
// success! update order record
|
547 |
+
if ( $response->transaction_approved() ) {
|
548 |
+
|
549 |
+
$last_four = substr( $order->payment->account_number, -4 );
|
550 |
+
|
551 |
+
// use direct card type if set, or try to guess it from card number
|
552 |
+
if ( ! empty( $order->payment->card_type ) ) {
|
553 |
+
$card_type = $order->payment->card_type;
|
554 |
+
} elseif ( $first_four = substr( $order->payment->account_number, 0, 4 ) ) {
|
555 |
+
$card_type = Payment_Gateway_Helper::card_type_from_account_number( $first_four );
|
556 |
+
} else {
|
557 |
+
$card_type = 'card';
|
558 |
+
}
|
559 |
+
|
560 |
+
// credit card order note
|
561 |
+
$message = sprintf(
|
562 |
+
/* translators: Placeholders: %1$s - payment method title, %2$s - environment ("Test"), %3$s - transaction type (authorization/charge), %4$s - card type (mastercard, visa, ...), %5$s - last four digits of the card */
|
563 |
+
esc_html__( '%1$s %2$s %3$s Approved: %4$s ending in %5$s', 'woocommerce-square' ),
|
564 |
+
$this->get_method_title(),
|
565 |
+
$this->is_test_environment() ? esc_html_x( 'Test', 'noun, software environment', 'woocommerce-square' ) : '',
|
566 |
+
$this->perform_credit_card_authorization( $order ) ? esc_html_x( 'Authorization', 'credit card transaction type', 'woocommerce-square' ) : esc_html_x( 'Charge', 'noun, credit card transaction type', 'woocommerce-square' ),
|
567 |
+
Payment_Gateway_Helper::payment_type_to_name( $card_type ),
|
568 |
+
$last_four
|
569 |
+
);
|
570 |
+
|
571 |
+
// add the expiry date if it is available
|
572 |
+
if ( ! empty( $order->payment->exp_month ) && ! empty( $order->payment->exp_year ) ) {
|
573 |
+
|
574 |
+
$message .= ' ' . sprintf(
|
575 |
+
/** translators: Placeholders: %s - credit card expiry date */
|
576 |
+
__( '(expires %s)', 'woocommerce-square' ),
|
577 |
+
esc_html( $order->payment->exp_month . '/' . substr( $order->payment->exp_year, -2 ) )
|
578 |
+
);
|
579 |
+
}
|
580 |
+
|
581 |
+
// adds the transaction id (if any) to the order note
|
582 |
+
if ( $response->get_transaction_id() ) {
|
583 |
+
/* translators: Placeholders: %s - transaction ID */
|
584 |
+
$message .= ' ' . sprintf( esc_html__( '(Transaction ID %s)', 'woocommerce-square' ), $response->get_transaction_id() );
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* Direct Gateway Credit Card Transaction Approved Order Note Filter.
|
589 |
+
*
|
590 |
+
* Allow actors to modify the order note added when a Credit Card transaction
|
591 |
+
* is approved.
|
592 |
+
*
|
593 |
+
* @since 3.0.0
|
594 |
+
*
|
595 |
+
* @param string $message order note
|
596 |
+
* @param \WC_Order $order order object
|
597 |
+
* @param Payment_Gateway_API_Response_Interface $response transaction response
|
598 |
+
* @param Payment_Gateway_Direct $this instance
|
599 |
+
*/
|
600 |
+
$message = apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_credit_card_transaction_approved_order_note', $message, $order, $response, $this );
|
601 |
+
|
602 |
+
$order->add_order_note( $message );
|
603 |
+
|
604 |
+
}
|
605 |
+
|
606 |
+
return $response;
|
607 |
+
|
608 |
+
}
|
609 |
+
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Create a transaction.
|
613 |
+
*
|
614 |
+
* @since 3.0.0
|
615 |
+
*
|
616 |
+
* @param \WC_Order $order the order object
|
617 |
+
* @return bool
|
618 |
+
* @throws \Exception
|
619 |
+
*/
|
620 |
+
protected function do_transaction( $order ) {
|
621 |
+
|
622 |
+
// perform the credit card or check transaction
|
623 |
+
if ( $this->is_credit_card_gateway() ) {
|
624 |
+
$response = $this->do_credit_card_transaction( $order );
|
625 |
+
} else {
|
626 |
+
$do_payment_type_transaction = 'do_' . $this->get_payment_type() . '_transaction';
|
627 |
+
$response = $this->$do_payment_type_transaction( $order );
|
628 |
+
}
|
629 |
+
|
630 |
+
// handle the response
|
631 |
+
if ( $response->transaction_approved() || $response->transaction_held() ) {
|
632 |
+
|
633 |
+
if ( $this->supports_tokenization() && 0 != $order->get_user_id() && $this->get_payment_tokens_handler()->should_tokenize() &&
|
634 |
+
( $order->payment_total > 0 && ( $this->tokenize_with_sale() || $this->tokenize_after_sale() ) ) ) {
|
635 |
+
|
636 |
+
try {
|
637 |
+
$order = $this->get_payment_tokens_handler()->create_token( $order, $response );
|
638 |
+
} catch ( \Exception $e ) {
|
639 |
+
|
640 |
+
// handle the case of a "tokenize-after-sale" request failing by marking the order as on-hold with an explanatory note
|
641 |
+
if ( ! $response->transaction_held() && ! ( $this->supports( self::FEATURE_CREDIT_CARD_AUTHORIZATION ) && $this->perform_credit_card_authorization( $order ) ) ) {
|
642 |
+
|
643 |
+
// transaction has already been successful, but we've encountered an issue with the post-tokenization, add an order note to that effect and continue on
|
644 |
+
$message = sprintf(
|
645 |
+
/* translators: Placeholders: %s - failure message */
|
646 |
+
esc_html__( 'Tokenization Request Failed: %s', 'woocommerce-square' ),
|
647 |
+
$e->getMessage()
|
648 |
+
);
|
649 |
+
|
650 |
+
$this->mark_order_as_held( $order, $message, $response );
|
651 |
+
|
652 |
+
} else {
|
653 |
+
|
654 |
+
// transaction has already been successful, but we've encountered an issue with the post-tokenization, add an order note to that effect and continue on
|
655 |
+
$message = sprintf(
|
656 |
+
/* translators: Placeholders: %1$s - payment method title, %2$s - failure message */
|
657 |
+
esc_html__( '%1$s Tokenization Request Failed: %2$s', 'woocommerce-square' ),
|
658 |
+
$this->get_method_title(),
|
659 |
+
$e->getMessage()
|
660 |
+
);
|
661 |
+
|
662 |
+
$order->add_order_note( $message );
|
663 |
+
}
|
664 |
+
}
|
665 |
+
}
|
666 |
+
|
667 |
+
// add the standard transaction data
|
668 |
+
$this->add_transaction_data( $order, $response );
|
669 |
+
|
670 |
+
// allow the concrete class to add any gateway-specific transaction data to the order
|
671 |
+
$this->add_payment_gateway_transaction_data( $order, $response );
|
672 |
+
|
673 |
+
// if the transaction was held (ie fraud validation failure) mark it as such
|
674 |
+
// TODO: consider checking whether the response *was* an authorization, rather than blanket-assuming it was because of the settings. There are times when an auth will be used rather than charge, ie when performing in-plugin AVS handling (moneris)
|
675 |
+
if ( $response->transaction_held() || ( $this->supports( self::FEATURE_CREDIT_CARD_AUTHORIZATION ) && $this->perform_credit_card_authorization( $order ) ) ) {
|
676 |
+
// TODO: need to make this more flexible, and not force the message to 'Authorization only transaction' for auth transactions (re moneris efraud handling)
|
677 |
+
/* translators: This is a message describing that the transaction in question only performed a credit card authorization and did not capture any funds. */
|
678 |
+
$this->mark_order_as_held( $order, $this->supports( self::FEATURE_CREDIT_CARD_AUTHORIZATION ) && $this->perform_credit_card_authorization( $order ) ? esc_html__( 'Authorization only transaction', 'woocommerce-square' ) : $response->get_status_message(), $response );
|
679 |
+
}
|
680 |
+
|
681 |
+
return true;
|
682 |
+
|
683 |
+
} else { // failure
|
684 |
+
|
685 |
+
return $this->do_transaction_failed_result( $order, $response );
|
686 |
+
|
687 |
+
}
|
688 |
+
}
|
689 |
+
|
690 |
+
|
691 |
+
/** Add Payment Method feature ********************************************/
|
692 |
+
|
693 |
+
|
694 |
+
/**
|
695 |
+
* Entry method for the Add Payment Method feature flow. Note this is *not*
|
696 |
+
* stubbed in the WC_Payment_Gateway abstract class, but is called if the
|
697 |
+
* gateway declares support for it.
|
698 |
+
*
|
699 |
+
* @since 3.0.0
|
700 |
+
*/
|
701 |
+
public function add_payment_method() {
|
702 |
+
|
703 |
+
assert( $this->supports_add_payment_method() );
|
704 |
+
|
705 |
+
$order = $this->get_order_for_add_payment_method();
|
706 |
+
|
707 |
+
try {
|
708 |
+
|
709 |
+
$result = $this->do_add_payment_method_transaction( $order );
|
710 |
+
|
711 |
+
} catch ( \Exception $e ) {
|
712 |
+
|
713 |
+
$result = array(
|
714 |
+
/* translators: Placeholders: %s - failure message. Payment method as in a specific credit card, e-check or bank account */
|
715 |
+
'message' => sprintf( esc_html__( 'Oops, adding your new payment method failed: %s', 'woocommerce-square' ), $e->getMessage() ),
|
716 |
+
'success' => false,
|
717 |
+
);
|
718 |
+
}
|
719 |
+
|
720 |
+
Square_Helper::wc_add_notice( $result['message'], $result['success'] ? 'success' : 'error' );
|
721 |
+
|
722 |
+
if ( $result['success'] ) {
|
723 |
+
$redirect_url = wc_get_account_endpoint_url( 'payment-methods' );
|
724 |
+
} else {
|
725 |
+
$redirect_url = wc_get_endpoint_url( 'add-payment-method' );
|
726 |
+
}
|
727 |
+
|
728 |
+
wp_safe_redirect( $redirect_url );
|
729 |
+
exit();
|
730 |
+
}
|
731 |
+
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Perform the transaction to add the customer's payment method to their
|
735 |
+
* account
|
736 |
+
*
|
737 |
+
* @since 3.0.0
|
738 |
+
* @return array result with success/error message and request status (success/failure)
|
739 |
+
* @throws \Exception
|
740 |
+
*/
|
741 |
+
protected function do_add_payment_method_transaction( \WC_Order $order ) {
|
742 |
+
|
743 |
+
$response = $this->get_api()->tokenize_payment_method( $order );
|
744 |
+
|
745 |
+
if ( $response->transaction_approved() ) {
|
746 |
+
|
747 |
+
$token = $response->get_payment_token();
|
748 |
+
|
749 |
+
// set the token to the user account
|
750 |
+
$this->get_payment_tokens_handler()->add_token( $order->get_user_id(), $token );
|
751 |
+
|
752 |
+
// order note based on gateway type
|
753 |
+
if ( $this->is_credit_card_gateway() ) {
|
754 |
+
|
755 |
+
/* translators: Payment method as in a specific credit card. Placeholders: %1$s - card type (visa, mastercard, ...), %2$s - last four digits of the card, %3$s - card expiry date */
|
756 |
+
$message = sprintf( esc_html__( 'Nice! New payment method added: %1$s ending in %2$s (expires %3$s)', 'woocommerce-square' ),
|
757 |
+
$token->get_type_full(),
|
758 |
+
$token->get_last_four(),
|
759 |
+
$token->get_exp_date()
|
760 |
+
);
|
761 |
+
|
762 |
+
} else {
|
763 |
+
/* translators: Payment method as in a specific credit card, e-check or bank account */
|
764 |
+
$message = esc_html__( 'Nice! New payment method added.', 'woocommerce-square' );
|
765 |
+
}
|
766 |
+
|
767 |
+
// add transaction data to user meta
|
768 |
+
$this->add_add_payment_method_transaction_data( $response );
|
769 |
+
|
770 |
+
// add customer data, primarily customer ID to user meta
|
771 |
+
$this->add_add_payment_method_customer_data( $order, $response );
|
772 |
+
|
773 |
+
/**
|
774 |
+
* Fires after a new payment method is added by a customer.
|
775 |
+
*
|
776 |
+
* @since 3.0.0
|
777 |
+
*
|
778 |
+
* @param string $token_id new token ID
|
779 |
+
* @param int $user_id user ID
|
780 |
+
* @param Payment_Gateway_API_Response_Interface $response API response object
|
781 |
+
*/
|
782 |
+
do_action( 'wc_payment_gateway_' . $this->get_id() . '_payment_method_added', $token->get_id(), $order->get_user_id(), $response );
|
783 |
+
|
784 |
+
$result = array( 'message' => $message, 'success' => true );
|
785 |
+
|
786 |
+
} else {
|
787 |
+
|
788 |
+
if ( $response->get_status_code() && $response->get_status_message() ) {
|
789 |
+
$message = sprintf( esc_html__( 'Status code %s: %s', 'woocommerce-square' ), $response->get_status_code(), $response->get_status_message() );
|
790 |
+
} elseif ( $response->get_status_code() ) {
|
791 |
+
$message = sprintf( esc_html__( 'Status code: %s', 'woocommerce-square' ), $response->get_status_code() );
|
792 |
+
} elseif ( $response->get_status_message() ) {
|
793 |
+
$message = sprintf( esc_html__( 'Status message: %s', 'woocommerce-square' ), $response->get_status_message() );
|
794 |
+
} else {
|
795 |
+
$message = 'Unknown Error';
|
796 |
+
}
|
797 |
+
|
798 |
+
$result = array( 'message' => $message, 'success' => false );
|
799 |
+
}
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Add Payment Method Transaction Result Filter.
|
803 |
+
*
|
804 |
+
* Filter the result data from an add payment method transaction attempt -- this
|
805 |
+
* can be used to control the notice message displayed and whether the
|
806 |
+
* user is redirected back to the My Account page or remains on the add
|
807 |
+
* new payment method screen
|
808 |
+
*
|
809 |
+
* @since 3.0.0
|
810 |
+
* @param array $result {
|
811 |
+
* @type string $message notice message to render
|
812 |
+
* @type bool $success true to redirect to my account, false to stay on page
|
813 |
+
* }
|
814 |
+
* @param WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Create_Payment_Token_Response $response instance
|
815 |
+
* @param \WC_Order $order order instance
|
816 |
+
* @param Payment_Gateway_Direct $this direct gateway instance
|
817 |
+
*/
|
818 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_add_payment_method_transaction_result', $result, $response, $order, $this );
|
819 |
+
}
|
820 |
+
|
821 |
+
|
822 |
+
/**
|
823 |
+
* Creates the order required for adding a new payment method. Note that
|
824 |
+
* a mock order is generated as there is no actual order associated with the
|
825 |
+
* request.
|
826 |
+
*
|
827 |
+
* @since 3.0.0
|
828 |
+
* @return \WC_Order generated order object
|
829 |
+
*/
|
830 |
+
protected function get_order_for_add_payment_method() {
|
831 |
+
|
832 |
+
// mock order, as all gateway API implementations require an order object for tokenization
|
833 |
+
$order = new \WC_Order( 0 );
|
834 |
+
$order = $this->get_order( $order );
|
835 |
+
|
836 |
+
$user = get_userdata( get_current_user_id() );
|
837 |
+
|
838 |
+
$properties = array(
|
839 |
+
'currency' => get_woocommerce_currency(), // default to base store currency
|
840 |
+
'customer_id' => $user->ID,
|
841 |
+
);
|
842 |
+
|
843 |
+
$defaults = array(
|
844 |
+
// billing
|
845 |
+
'billing_first_name' => '',
|
846 |
+
'billing_last_name' => '',
|
847 |
+
'billing_company' => '',
|
848 |
+
'billing_address_1' => '',
|
849 |
+
'billing_address_2' => '',
|
850 |
+
'billing_city' => '',
|
851 |
+
'billing_postcode' => '',
|
852 |
+
'billing_state' => '',
|
853 |
+
'billing_country' => '',
|
854 |
+
'billing_phone' => '',
|
855 |
+
'billing_email' => $user->user_email,
|
856 |
+
|
857 |
+
// shipping
|
858 |
+
'shipping_first_name' => '',
|
859 |
+
'shipping_last_name' => '',
|
860 |
+
'shipping_company' => '',
|
861 |
+
'shipping_address_1' => '',
|
862 |
+
'shipping_address_2' => '',
|
863 |
+
'shipping_city' => '',
|
864 |
+
'shipping_postcode' => '',
|
865 |
+
'shipping_state' => '',
|
866 |
+
'shipping_country' => '',
|
867 |
+
);
|
868 |
+
|
869 |
+
foreach ( $defaults as $prop => $value ) {
|
870 |
+
|
871 |
+
$value = ! empty( $user->$prop ) ? $user->$prop : $value;
|
872 |
+
|
873 |
+
if ( ! empty( $value ) ) {
|
874 |
+
$properties[ $prop ] = $value;
|
875 |
+
}
|
876 |
+
}
|
877 |
+
|
878 |
+
$order = Order_Compatibility::set_props( $order, $properties );
|
879 |
+
|
880 |
+
// other default info
|
881 |
+
$order->customer_id = $this->get_customer_id( $order->get_user_id() );
|
882 |
+
|
883 |
+
/* translators: Placeholders: %1$s - site title, %2$s - customer email. Payment method as in a specific credit card, e-check or bank account */
|
884 |
+
$order->description = sprintf( esc_html__( '%1$s - Add Payment Method for %2$s', 'woocommerce-square' ), sanitize_text_field( Square_Helper::get_site_name() ), $properties['billing_email'] );
|
885 |
+
|
886 |
+
// force zero amount
|
887 |
+
$order->payment_total = '0.00';
|
888 |
+
|
889 |
+
/**
|
890 |
+
* Direct Gateway Get Order for Add Payment Method Filter.
|
891 |
+
*
|
892 |
+
* Allow actors to modify the order object used for an add payment method
|
893 |
+
* transaction.
|
894 |
+
*
|
895 |
+
* @since 3.0.0
|
896 |
+
* @param \WC_Order $order order object
|
897 |
+
* @param Payment_Gateway_Direct $this instance
|
898 |
+
*/
|
899 |
+
return apply_filters( 'wc_payment_gateway_' . $this->get_id() . '_get_order_for_add_payment_method', $order, $this );
|
900 |
+
}
|
901 |
+
|
902 |
+
|
903 |
+
/**
|
904 |
+
* Add customer data as part of the add payment method transaction, primarily
|
905 |
+
* customer ID
|
906 |
+
*
|
907 |
+
* @since 3.0.0
|
908 |
+
* @param \WC_Order $order mock order
|
909 |
+
* @param \WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Create_Payment_Token_Response $response
|
910 |
+
*/
|
911 |
+
protected function add_add_payment_method_customer_data( $order, $response ) {
|
912 |
+
$user_id = $order->get_user_id();
|
913 |
+
|
914 |
+
// set customer ID from response if available
|
915 |
+
if ( $this->supports_customer_id() && method_exists( $response, 'get_customer_id' ) && $response->get_customer_id() ) {
|
916 |
+
|
917 |
+
$order->customer_id = $customer_id = $response->get_customer_id();
|
918 |
+
|
919 |
+
} else {
|
920 |
+
|
921 |
+
// default to the customer ID on "order"
|
922 |
+
$customer_id = $order->customer_id;
|
923 |
+
}
|
924 |
+
|
925 |
+
// update the user
|
926 |
+
if ( 0 != $user_id ) {
|
927 |
+
$this->update_customer_id( $user_id, $customer_id );
|
928 |
+
}
|
929 |
+
}
|
930 |
+
|
931 |
+
|
932 |
+
/**
|
933 |
+
* Adds data from the add payment method transaction, primarily:
|
934 |
+
*
|
935 |
+
* + transaction ID
|
936 |
+
* + transaction date
|
937 |
+
* + transaction environment
|
938 |
+
*
|
939 |
+
* @since 3.0.0
|
940 |
+
*
|
941 |
+
* @param WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Create_Payment_Token_Response $response
|
942 |
+
*/
|
943 |
+
protected function add_add_payment_method_transaction_data( $response ) {
|
944 |
+
|
945 |
+
$user_meta_key = '_wc_' . $this->get_id() . '_add_payment_method_transaction_data';
|
946 |
+
|
947 |
+
$data = (array) get_user_meta( get_current_user_id(), $user_meta_key, true );
|
948 |
+
|
949 |
+
$new_data = array(
|
950 |
+
'trans_id' => $response->get_transaction_id() ? $response->get_transaction_id() : null,
|
951 |
+
'trans_date' => current_time( 'mysql' ),
|
952 |
+
'environment' => $this->get_environment(),
|
953 |
+
);
|
954 |
+
|
955 |
+
$data[] = array_merge( $new_data, $this->get_add_payment_method_payment_gateway_transaction_data( $response ) );
|
956 |
+
|
957 |
+
// only keep the 5 most recent transactions
|
958 |
+
if ( count( $data ) > 5 ) {
|
959 |
+
array_shift( $data );
|
960 |
+
}
|
961 |
+
|
962 |
+
update_user_meta( get_current_user_id(), $user_meta_key, array_filter( $data ) );
|
963 |
+
}
|
964 |
+
|
965 |
+
|
966 |
+
/**
|
967 |
+
* Allow gateway implementations to add additional data to the data saved
|
968 |
+
* during the add payment method transaction
|
969 |
+
*
|
970 |
+
* @since 3.0.0
|
971 |
+
* @param WooCommerce\Square\Framework\PaymentGateway\Api\Payment_Gateway_API_Create_Payment_Token_Response $response create payment token response
|
972 |
+
* @return array
|
973 |
+
*/
|
974 |
+
protected function get_add_payment_method_payment_gateway_transaction_data( $response ) {
|
975 |
+
|
976 |
+
// stub method
|
977 |
+
return array();
|
978 |
+
}
|
979 |
+
|
980 |
+
|
981 |
+
/** Getters ******************************************************/
|
982 |
+
|
983 |
+
|
984 |
+
/**
|
985 |
+
* Returns true if this is a direct type gateway
|
986 |
+
*
|
987 |
+
* @since 3.0.0
|
988 |
+
* @return boolean if this is a direct payment gateway
|
989 |
+
*/
|
990 |
+
public function is_direct_gateway() {
|
991 |
+
return true;
|
992 |
+
}
|
993 |
+
|
994 |
+
|
995 |
+
/**
|
996 |
+
* Returns true if a transaction should be forced (meaning payment
|
997 |
+
* processed even if the order amount is 0). This is useful mostly for
|
998 |
+
* testing situations
|
999 |
+
*
|
1000 |
+
* @since 3.0.0
|
1001 |
+
* @return boolean true if the transaction request should be forced
|
1002 |
+
*/
|
1003 |
+
public function transaction_forced() {
|
1004 |
+
return false;
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
}
|
includes/Framework/PaymentGateway/Payment_Gateway_Helper.php
ADDED
@@ -0,0 +1,238 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway;
|
4 |
+
|
5 |
+
defined( 'ABSPATH' ) or exit;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Payment Gateway Helper Class
|
9 |
+
*
|
10 |
+
* @since 3.0.0
|
11 |
+
*/
|
12 |
+
class Payment_Gateway_Helper {
|
13 |
+
|
14 |
+
|
15 |
+
/** @var string the Visa card type ID **/
|
16 |
+
const CARD_TYPE_VISA = 'visa';
|
17 |
+
|
18 |
+
/** @var string the MasterCard card type ID **/
|
19 |
+
const CARD_TYPE_MASTERCARD = 'mastercard';
|
20 |
+
|
21 |
+
/** @var string the American Express card type ID **/
|
22 |
+
const CARD_TYPE_AMEX = 'amex';
|
23 |
+
|
24 |
+
/** @var string the Diners Club card type ID **/
|
25 |
+
const CARD_TYPE_DINERSCLUB = 'dinersclub';
|
26 |
+
|
27 |
+
/** @var string the Discover card type ID **/
|
28 |
+
const CARD_TYPE_DISCOVER = 'discover';
|
29 |
+
|
30 |
+
/** @var string the JCB card type ID **/
|
31 |
+
const CARD_TYPE_JCB = 'jcb';
|
32 |
+
|
33 |
+
/** @var string the CarteBleue card type ID **/
|
34 |
+
const CARD_TYPE_CARTEBLEUE = 'cartebleue';
|
35 |
+
|
36 |
+
/** @var string the Maestro card type ID **/
|
37 |
+
const CARD_TYPE_MAESTRO = 'maestro';
|
38 |
+
|
39 |
+
/** @var string the Laser card type ID **/
|
40 |
+
const CARD_TYPE_LASER = 'laser';
|
41 |
+
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Perform standard luhn check. Algorithm:
|
45 |
+
*
|
46 |
+
* 1. Double the value of every second digit beginning with the second-last right-hand digit.
|
47 |
+
* 2. Add the individual digits comprising the products obtained in step 1 to each of the other digits in the original number.
|
48 |
+
* 3. Subtract the total obtained in step 2 from the next higher number ending in 0.
|
49 |
+
* 4. This number should be the same as the last digit (the check digit). If the total obtained in step 2 is a number ending in zero (30, 40 etc.), the check digit is 0.
|
50 |
+
*
|
51 |
+
* @since 3.0.0
|
52 |
+
* @param string $account_number the credit card number to check
|
53 |
+
* @return bool true if $account_number passes the check, false otherwise
|
54 |
+
*/
|
55 |
+
public static function luhn_check( $account_number ) {
|
56 |
+
|
57 |
+
for ( $sum = 0, $i = 0, $ix = strlen( $account_number ); $i < $ix - 1; $i++) {
|
58 |
+
|
59 |
+
$weight = substr( $account_number, $ix - ( $i + 2 ), 1 ) * ( 2 - ( $i % 2 ) );
|
60 |
+
$sum += $weight < 10 ? $weight : $weight - 9;
|
61 |
+
|
62 |
+
}
|
63 |
+
|
64 |
+
return substr( $account_number, $ix - 1 ) == ( ( 10 - $sum % 10 ) % 10 );
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Normalize a card type to a standard type ID and account for variations.
|
70 |
+
*
|
71 |
+
* @since 3.0.0
|
72 |
+
* @param string $card_type the card type to normalize
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public static function normalize_card_type( $card_type ) {
|
76 |
+
|
77 |
+
$card_types = self::get_card_types();
|
78 |
+
|
79 |
+
$card_type = strtolower( $card_type );
|
80 |
+
|
81 |
+
// stop here if the provided card type is already normalized
|
82 |
+
if ( in_array( $card_type, array_keys( $card_types ), true ) ) {
|
83 |
+
return $card_type;
|
84 |
+
}
|
85 |
+
|
86 |
+
$variations = wp_list_pluck( $card_types, 'variations' );
|
87 |
+
|
88 |
+
// if the provided card type matches a known variation, return the normalized card type
|
89 |
+
foreach ( $variations as $valid_type => $vars ) {
|
90 |
+
|
91 |
+
if ( in_array( $card_type, $vars, true ) ) {
|
92 |
+
$card_type = $valid_type;
|
93 |
+
break;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
// otherwise, let it through unaltered
|
98 |
+
return $card_type;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Determine the credit card type from a given account number (only first 4
|
104 |
+
* required)
|
105 |
+
*
|
106 |
+
* @since 3.0.0
|
107 |
+
* @param string $account_number the credit card account number
|
108 |
+
* @return string the credit card type
|
109 |
+
*/
|
110 |
+
public static function card_type_from_account_number( $account_number ) {
|
111 |
+
|
112 |
+
// card type regex patterns from https://github.com/stripe/jquery.payment/blob/master/src/jquery.payment.coffee
|
113 |
+
$types = array(
|
114 |
+
self::CARD_TYPE_VISA => '/^4/',
|
115 |
+
self::CARD_TYPE_MASTERCARD => '/^(5[1-5]|2[2-7])/',
|
116 |
+
self::CARD_TYPE_AMEX => '/^3[47]/',
|
117 |
+
self::CARD_TYPE_DINERSCLUB => '/^(36|38|30[0-5])/',
|
118 |
+
self::CARD_TYPE_DISCOVER => '/^(6011|65|64[4-9]|622)/',
|
119 |
+
self::CARD_TYPE_JCB => '/^35/',
|
120 |
+
self::CARD_TYPE_MAESTRO => '/^(5018|5020|5038|6304|6759|676[1-3])/',
|
121 |
+
self::CARD_TYPE_LASER => '/^(6706|6771|6709)/',
|
122 |
+
);
|
123 |
+
|
124 |
+
foreach ( $types as $type => $pattern ) {
|
125 |
+
|
126 |
+
if ( 1 === preg_match( $pattern, $account_number ) ) {
|
127 |
+
return $type;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
return null;
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Translates a credit card type or bank account name to a full name,
|
137 |
+
* e.g. 'mastercard' => 'MasterCard' or 'savings' => 'eCheck'
|
138 |
+
*
|
139 |
+
* @since 3.0.0
|
140 |
+
* @param string $payment_type the credit card or bank type, ie 'mastercard', 'amex', 'checking'
|
141 |
+
* @return string the credit card or bank account name, ie 'MasterCard', 'American Express', 'Checking Account'
|
142 |
+
*/
|
143 |
+
public static function payment_type_to_name( $payment_type ) {
|
144 |
+
|
145 |
+
$name = '';
|
146 |
+
|
147 |
+
// normalize for backwards compatibility with gateways that pass the card type directly from Payment_Gateway::get_card_types()
|
148 |
+
$type = self::normalize_card_type( $payment_type );
|
149 |
+
|
150 |
+
// known payment type names, excluding credit cards
|
151 |
+
$payment_types = array(
|
152 |
+
'paypal' => esc_html__( 'PayPal', 'woocommerce-square' ),
|
153 |
+
'checking' => esc_html__( 'Checking Account', 'woocommerce-square' ),
|
154 |
+
'savings' => esc_html__( 'Savings Account', 'woocommerce-square' ),
|
155 |
+
'card' => esc_html__( 'Credit / Debit Card', 'woocommerce-square' ),
|
156 |
+
'bank' => esc_html__( 'Bank Account', 'woocommerce-square' ),
|
157 |
+
);
|
158 |
+
|
159 |
+
// add the credit card names
|
160 |
+
$payment_types = array_merge( wp_list_pluck( self::get_card_types(), 'name' ), $payment_types );
|
161 |
+
|
162 |
+
if ( isset( $payment_types[ $type ] ) ) {
|
163 |
+
$name = $payment_types[ $type ];
|
164 |
+
} elseif ( '' === $type ) {
|
165 |
+
$name = esc_html_x( 'Account', 'payment method type', 'woocommerce-square' );
|
166 |
+
} else {
|
167 |
+
$name = ucwords( str_replace( '-', ' ', $type ) );
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Payment Gateway Type to Name Filter.
|
172 |
+
*
|
173 |
+
* Allow actors to modify the name returned given a payment type.
|
174 |
+
*
|
175 |
+
* @since 3.0.0
|
176 |
+
* @param string $name nice payment type name, e.g. American Express
|
177 |
+
* @param string $type payment type, e.g. amex
|
178 |
+
*/
|
179 |
+
return apply_filters( 'wc_payment_gateway_payment_type_to_name', $name, $type );
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Gets the known card types and their variations.
|
185 |
+
*
|
186 |
+
* Returns the card types in the format:
|
187 |
+
*
|
188 |
+
* 'mastercard' {
|
189 |
+
* 'name' => 'MasterCard',
|
190 |
+
* 'variations' => array( 'mc' ),
|
191 |
+
* }
|
192 |
+
*
|
193 |
+
* @since 3.0.0
|
194 |
+
*
|
195 |
+
* @return array
|
196 |
+
*/
|
197 |
+
public static function get_card_types() {
|
198 |
+
|
199 |
+
return array(
|
200 |
+
self::CARD_TYPE_VISA => array(
|
201 |
+
'name' => esc_html_x( 'Visa', 'credit card type', 'woocommerce-square' ),
|
202 |
+
'variations' => array(),
|
203 |
+
),
|
204 |
+
self::CARD_TYPE_MASTERCARD => array(
|
205 |
+
'name' => esc_html_x( 'MasterCard', 'credit card type', 'woocommerce-square' ),
|
206 |
+
'variations' => array( 'mc' ),
|
207 |
+
),
|
208 |
+
self::CARD_TYPE_AMEX => array(
|
209 |
+
'name' => esc_html_x( 'American Express', 'credit card type', 'woocommerce-square' ),
|
210 |
+
'variations' => array( 'americanexpress' ),
|
211 |
+
),
|
212 |
+
self::CARD_TYPE_DINERSCLUB => array(
|
213 |
+
'name' => esc_html_x( 'Diners Club', 'credit card type', 'woocommerce-square' ),
|
214 |
+
'variations' => array( 'diners' ),
|
215 |
+
),
|
216 |
+
self::CARD_TYPE_DISCOVER => array(
|
217 |
+
'name' => esc_html_x( 'Discover', 'credit card type', 'woocommerce-square' ),
|
218 |
+
'variations' => array( 'disc' ),
|
219 |
+
),
|
220 |
+
self::CARD_TYPE_JCB => array(
|
221 |
+
'name' => esc_html_x( 'JCB', 'credit card type', 'woocommerce-square' ),
|
222 |
+
'variations' => array(),
|
223 |
+
),
|
224 |
+
self::CARD_TYPE_CARTEBLEUE => array(
|
225 |
+
'name' => esc_html_x( 'CarteBleue', 'credit card type', 'woocommerce-square' ),
|
226 |
+
'variations' => array(),
|
227 |
+
),
|
228 |
+
self::CARD_TYPE_MAESTRO => array(
|
229 |
+
'name' => esc_html_x( 'Maestro', 'credit card type', 'woocommerce-square' ),
|
230 |
+
'variations' => array(),
|
231 |
+
),
|
232 |
+
self::CARD_TYPE_LASER => array(
|
233 |
+
'name' => esc_html_x( 'Laser', 'credit card type', 'woocommerce-square' ),
|
234 |
+
'variations' => array(),
|
235 |
+
),
|
236 |
+
);
|
237 |
+
}
|
238 |
+
}
|
includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php
ADDED
@@ -0,0 +1,970 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WooCommerce\Square\Framework\PaymentGateway;
|
4 |
+
use WooCommerce\Square\Plugin;
|
5 |
+
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Payment_Gateway_Payment_Token;
|
6 |
+
use WooCommerce\Square\Framework\Square_Helper;
|
7 |
+
|
8 |
+
defined( 'ABSPATH' ) or exit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* My Payment Methods Class
|
12 |
+
*
|
13 |
+
* Renders the My Payment Methods table on the My Account page and handles
|
14 |
+
* any associated actions (deleting a payment method, etc)
|
15 |
+
*
|
16 |
+
* @since 3.0.0
|
17 |
+
*/
|
18 |
+
class Payment_Gateway_My_Payment_Methods {
|
19 |
+
|
20 |
+
|
21 |
+
/** @var Payment_Gateway_Plugin */
|
22 |
+
protected $plugin;
|
23 |
+
|
24 |
+
/** @var Payment_Gateway_Payment_Token[] array of token objects */
|
25 |
+
protected $tokens;
|
26 |
+
|
27 |
+
/** @var Payment_Gateway_Payment_Token[] array of token objects */
|
28 |
+
protected $credit_card_tokens;
|
29 |
+
|
30 |
+
/** @var Payment_Gateway_Payment_Token[] array of token objects */
|
31 |
+
protected $echeck_tokens;
|
32 |
+
|
33 |
+
/** @var bool true if there are tokens */
|
34 |
+
protected $has_tokens;
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Setup Class
|
39 |
+
*
|
40 |
+
* Note: this constructor executes during the `wp` action
|
41 |
+
*
|
42 |
+
* @param Payment_Gateway_Plugin $plugin gateway plugin
|
43 |
+
* @since 3.0.0
|
44 |
+
*/
|
45 |
+
public function __construct( $plugin ) {
|
46 |
+
|
47 |
+
$this->plugin = $plugin;
|
48 |
+
|
49 |
+
add_action( 'wp', array( $this, 'init' ) );
|
50 |
+
|
51 |
+
// save a payment method via AJAX
|
52 |
+
add_action( 'wp_ajax_wc_' . $this->get_plugin()->get_id() . '_save_payment_method', array( $this, 'ajax_save_payment_method' ) );
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Initializes the My Payment Methods table
|
58 |
+
*
|
59 |
+
* @since 3.0.0
|
60 |
+
*/
|
61 |
+
public function init() {
|
62 |
+
|
63 |
+
if ( ! $this->is_payment_methods_page() ) {
|
64 |
+
return;
|
65 |
+
}
|
66 |
+
|
67 |
+
// load all tokens for the given plugin
|
68 |
+
$this->load_tokens();
|
69 |
+
|
70 |
+
// styles/scripts
|
71 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_styles_scripts' ) );
|
72 |
+
|
73 |
+
// render the My Payment Methods section
|
74 |
+
// TODO: merge our payment methods data into the core table and remove this in a future version {CW 2016-05-17}
|
75 |
+
add_action( 'woocommerce_after_account_payment_methods', array( $this, 'render' ) );
|
76 |
+
add_action( 'woocommerce_after_account_payment_methods', array( $this, 'render_js' ) );
|
77 |
+
|
78 |
+
// handle payment method deletion, etc.
|
79 |
+
$this->handle_payment_method_actions();
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Enqueue frontend CSS/JS
|
85 |
+
*
|
86 |
+
* @since 3.0.0
|
87 |
+
*/
|
88 |
+
public function maybe_enqueue_styles_scripts() {
|
89 |
+
|
90 |
+
$handle = 'wc-square-payment-gateway-my-payment-methods';
|
91 |
+
|
92 |
+
// if there are tokens to display, add the custom JS
|
93 |
+
if ( $this->has_tokens ) {
|
94 |
+
|
95 |
+
wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array( 'jquery' ), WC_VERSION, true );
|
96 |
+
|
97 |
+
wp_enqueue_style( $handle, $this->get_plugin()->get_plugin_url() . '/assets/css/frontend/' . $handle . '.min.css', array( 'dashicons' ), Plugin::VERSION );
|
98 |
+
|
99 |
+
wp_enqueue_script( $handle, $this->get_plugin()->get_plugin_url() . '/assets/js/frontend/' . $handle . '.min.js', array( 'jquery-tiptip', 'jquery' ), Plugin::VERSION );
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Get the the available tokens for each plugin gateway and combine them
|
106 |
+
*
|
107 |
+
* Tokens are also separated into Credit Card and eCheck-specific class members
|
108 |
+
* for convenience.
|
109 |
+
*
|
110 |
+
* @since 3.0.0
|
111 |
+
*/
|
112 |
+
protected function load_tokens() {
|
113 |
+
|
114 |
+
if ( ! empty( $this->tokens ) ) {
|
115 |
+
return $this->tokens;
|
116 |
+
}
|
117 |
+
|
118 |
+
$this->credit_card_tokens = $this->echeck_tokens = array();
|
119 |
+
|
120 |
+
foreach ( $this->get_plugin()->get_gateways() as $gateway ) {
|
121 |
+
|
122 |
+
if ( ! $gateway->is_available() || ! ( $gateway->supports_tokenization() && $gateway->tokenization_enabled() ) ) {
|
123 |
+
continue;
|
124 |
+
}
|
125 |
+
|
126 |
+
foreach ( $gateway->get_payment_tokens_handler()->get_tokens( get_current_user_id() ) as $token ) {
|
127 |
+
|
128 |
+
// prevent duplicates, as some gateways will return all tokens in each each gateway
|
129 |
+
if ( isset( $this->credit_card_tokens[ $token->get_id() ] ) || isset( $this->echeck_tokens[ $token->get_id() ] ) ) {
|
130 |
+
continue;
|
131 |
+
}
|
132 |
+
|
133 |
+
if ( $token->is_credit_card() ) {
|
134 |
+
|
135 |
+
$this->credit_card_tokens[ $token->get_id() ] = $token;
|
136 |
+
|
137 |
+
}
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
// we don't use array_merge here since the indexes could be numeric
|
142 |
+
// and cause the indexes to be reset
|
143 |
+
$this->tokens = $this->credit_card_tokens + $this->echeck_tokens;
|
144 |
+
|
145 |
+
$this->has_tokens = ! empty( $this->tokens );
|
146 |
+
|
147 |
+
return $this->tokens;
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Render the payment methods table.
|
153 |
+
*
|
154 |
+
* @since 3.0.0
|
155 |
+
*/
|
156 |
+
public function render() {
|
157 |
+
|
158 |
+
if ( $this->has_tokens ) {
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Before My Payment Methods Table Action.
|
162 |
+
*
|
163 |
+
* Fired before the My Payment Methods table HTML is rendered.
|
164 |
+
*
|
165 |
+
* @since 3.0.0
|
166 |
+
*
|
167 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
168 |
+
*/
|
169 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_before_my_payment_method_table', $this );
|
170 |
+
|
171 |
+
echo $this->get_table_html();
|
172 |
+
|
173 |
+
/**
|
174 |
+
* After My Payment Methods Table Action.
|
175 |
+
*
|
176 |
+
* Fired after the My Payment Methods table HTML is rendered.
|
177 |
+
*
|
178 |
+
* @since 3.0.0
|
179 |
+
*
|
180 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
181 |
+
*/
|
182 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_after_my_payment_method_table', $this );
|
183 |
+
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Renders the JavaScript.
|
190 |
+
*
|
191 |
+
* @since 3.0.0
|
192 |
+
*/
|
193 |
+
public function render_js() {
|
194 |
+
|
195 |
+
$args = array(
|
196 |
+
'id' => $this->get_plugin()->get_id(),
|
197 |
+
'slug' => $this->get_plugin()->get_id_dasherized(),
|
198 |
+
'has_core_tokens' => (bool) wc_get_customer_saved_methods_list( get_current_user_id() ),
|
199 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
200 |
+
'ajax_nonce' => wp_create_nonce( 'wc_' . $this->get_plugin()->get_id() . '_save_payment_method' ),
|
201 |
+
'i18n' => array(
|
202 |
+
'edit_button' => esc_html__( 'Edit', 'woocommerce-square' ),
|
203 |
+
'cancel_button' => esc_html__( 'Cancel', 'woocommerce-square' ),
|
204 |
+
'save_error' => esc_html__( 'Oops, there was an error updating your payment method. Please try again.', 'woocommerce-square' ),
|
205 |
+
'delete_ays' => esc_html__( 'Are you sure you want to delete this payment method?', 'woocommerce-square' ),
|
206 |
+
),
|
207 |
+
);
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Filters the payment gateway payment methods JavaScript args.
|
211 |
+
*
|
212 |
+
* @since 3.0.0
|
213 |
+
*
|
214 |
+
* @param array $args arguments
|
215 |
+
* @param Payment_Gateway_My_Payment_Methods $handler payment methods handler
|
216 |
+
*/
|
217 |
+
$args = apply_filters( 'wc_payment_gateway_' . $this->get_plugin()->get_id() . '_payment_methods_js_args', $args, $this );
|
218 |
+
|
219 |
+
wc_enqueue_js( sprintf(
|
220 |
+
'window.wc_%1$s_payment_methods_handler = new %2$s( %3$s );',
|
221 |
+
esc_js( $this->get_plugin()->get_id() ),
|
222 |
+
esc_js( $this->get_js_handler_class() ),
|
223 |
+
wp_json_encode( $args )
|
224 |
+
) );
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Gets the JS handler class name.
|
230 |
+
*
|
231 |
+
* Plugins can override this for their own JS implementations.
|
232 |
+
*
|
233 |
+
* @since 3.0.0
|
234 |
+
*
|
235 |
+
* @return string
|
236 |
+
*/
|
237 |
+
protected function get_js_handler_class() {
|
238 |
+
|
239 |
+
return 'Square_Payment_Methods_Handler';
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Return the table HTML
|
244 |
+
*
|
245 |
+
* @since 3.0.0
|
246 |
+
* @return string table HTML
|
247 |
+
*/
|
248 |
+
public function get_table_html() {
|
249 |
+
|
250 |
+
$html = sprintf( '<table class="shop_table shop_table_responsive sv-wc-payment-gateway-my-payment-methods-table wc-%s-my-payment-methods">', sanitize_html_class( $this->get_plugin()->get_id_dasherized() ) );
|
251 |
+
|
252 |
+
$html .= $this->get_table_head_html();
|
253 |
+
|
254 |
+
$html .= $this->get_table_body_html();
|
255 |
+
|
256 |
+
$html .= '</table>';
|
257 |
+
|
258 |
+
/**
|
259 |
+
* My Payment Methods Table HTML Filter.
|
260 |
+
*
|
261 |
+
* Allow actors to modify the table HTML.
|
262 |
+
*
|
263 |
+
* @since 3.0.0
|
264 |
+
*
|
265 |
+
* @param string $html table HTML
|
266 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
267 |
+
*/
|
268 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_html', $html, $this );
|
269 |
+
}
|
270 |
+
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Return the table head HTML
|
274 |
+
*
|
275 |
+
* @since 3.0.0
|
276 |
+
* @return string table thead HTML
|
277 |
+
*/
|
278 |
+
protected function get_table_head_html() {
|
279 |
+
|
280 |
+
$html = '<thead><tr>';
|
281 |
+
|
282 |
+
foreach ( $this->get_table_headers() as $key => $title ) {
|
283 |
+
$html .= sprintf( '<th class="sv-wc-payment-gateway-my-payment-method-table-header sv-wc-payment-gateway-payment-method-header-%1$s wc-%2$s-payment-method-%1$s"><span class="nobr">%3$s</span></th>', sanitize_html_class( $key ), sanitize_html_class( $this->get_plugin()->get_id_dasherized() ), esc_html( $title ) );
|
284 |
+
}
|
285 |
+
|
286 |
+
$html .= '</tr></thead>';
|
287 |
+
|
288 |
+
/**
|
289 |
+
* My Payment Methods Table Head HTML Filter.
|
290 |
+
*
|
291 |
+
* Allow actors to modify the table head HTML.
|
292 |
+
*
|
293 |
+
* @since 3.0.0
|
294 |
+
*
|
295 |
+
* @param string $html table head HTML
|
296 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
297 |
+
*/
|
298 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_head_html', $html, $this );
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Return the table headers
|
304 |
+
*
|
305 |
+
* @since 3.0.0
|
306 |
+
* @return array of table headers in key => Title format
|
307 |
+
*/
|
308 |
+
protected function get_table_headers() {
|
309 |
+
|
310 |
+
$headers = array(
|
311 |
+
'title' => __( 'Method', 'woocommerce-square' ),
|
312 |
+
'details' => __( 'Details', 'woocommerce-square' ),
|
313 |
+
'expiry' => __( 'Expires', 'woocommerce-square' ),
|
314 |
+
'default' => __( 'Default?', 'woocommerce-square' ),
|
315 |
+
'actions' => __( 'Actions', 'woocommerce-square' ),
|
316 |
+
);
|
317 |
+
|
318 |
+
/**
|
319 |
+
* My Payment Methods Table Headers Filter.
|
320 |
+
*
|
321 |
+
* Allow actors to modify the table headers.
|
322 |
+
*
|
323 |
+
* @since 3.0.0
|
324 |
+
* @param array $headers table headers {
|
325 |
+
* @type string $title
|
326 |
+
* @type string $expiry
|
327 |
+
* @type string $actions
|
328 |
+
* }
|
329 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
330 |
+
*/
|
331 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_headers', $headers, $this );
|
332 |
+
}
|
333 |
+
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Return the table body HTML
|
337 |
+
*
|
338 |
+
* @since 3.0.0
|
339 |
+
* @return string table tbody HTML
|
340 |
+
*/
|
341 |
+
protected function get_table_body_html() {
|
342 |
+
|
343 |
+
$html = '<tbody>';
|
344 |
+
|
345 |
+
if ( $this->credit_card_tokens && $this->echeck_tokens ) {
|
346 |
+
|
347 |
+
$html .= sprintf(
|
348 |
+
'<tr class="sv-wc-payment-gateway-my-payment-methods-type-divider wc-%s-my-payment-methods-type-divider"><td colspan="%d">%s</td></tr>',
|
349 |
+
sanitize_html_class( $this->get_plugin()->get_id_dasherized() ),
|
350 |
+
count( $this->get_table_headers() ),
|
351 |
+
esc_html__( 'Credit/Debit Cards', 'woocommerce-square' )
|
352 |
+
);
|
353 |
+
|
354 |
+
$html .= $this->get_table_body_row_html( $this->credit_card_tokens );
|
355 |
+
|
356 |
+
$html .= sprintf(
|
357 |
+
'<tr class="sv-wc-payment-gateway-my-payment-methods-type-divider wc-%s-my-payment-methods-type-divider"><td colspan="%d">%s</td></tr>',
|
358 |
+
sanitize_html_class( $this->get_plugin()->get_id_dasherized() ),
|
359 |
+
count( $this->get_table_headers() ),
|
360 |
+
esc_html__( 'Bank Accounts', 'woocommerce-square' )
|
361 |
+
);
|
362 |
+
|
363 |
+
$html .= $this->get_table_body_row_html( $this->echeck_tokens );
|
364 |
+
|
365 |
+
} else {
|
366 |
+
|
367 |
+
$html .= $this->get_table_body_row_html( $this->tokens );
|
368 |
+
}
|
369 |
+
|
370 |
+
$html .= '</tbody>';
|
371 |
+
|
372 |
+
/**
|
373 |
+
* My Payment Methods Table Body HTML Filter.
|
374 |
+
*
|
375 |
+
* Allow actors to modify the table body HTML.
|
376 |
+
*
|
377 |
+
* @since 3.0.0
|
378 |
+
*
|
379 |
+
* @param string $html table body HTML
|
380 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
381 |
+
*/
|
382 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_body_html', $html, $this );
|
383 |
+
}
|
384 |
+
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Returns the table body row HTML, each row represents a single payment method.
|
388 |
+
*
|
389 |
+
* @since 3.0.0
|
390 |
+
*
|
391 |
+
* @param Payment_Gateway_Payment_Token[] $tokens token objects
|
392 |
+
* @return string table tbody > tr HTML
|
393 |
+
*/
|
394 |
+
protected function get_table_body_row_html( $tokens ) {
|
395 |
+
|
396 |
+
$html = '';
|
397 |
+
|
398 |
+
// for responsive table data-title attributes
|
399 |
+
$headers = $this->get_table_headers();
|
400 |
+
|
401 |
+
foreach ( $tokens as $token ) {
|
402 |
+
|
403 |
+
$method = $this->get_table_body_row_data( $token );
|
404 |
+
|
405 |
+
$html .= sprintf(
|
406 |
+
'<tr class="sv-wc-payment-gateway-my-payment-methods-method wc-%1$s-my-payment-methods-method %2$s" data-token-id="%3$s">',
|
407 |
+
sanitize_html_class( $this->get_plugin()->get_id_dasherized() ),
|
408 |
+
$token->is_default() ? 'default' : '',
|
409 |
+
esc_attr( $token->get_id() )
|
410 |
+
);
|
411 |
+
|
412 |
+
// Display the row data in the order of the headers
|
413 |
+
foreach ( $headers as $attribute => $attribute_title ) {
|
414 |
+
|
415 |
+
$value = isset( $method[ $attribute ] ) ? $method[ $attribute ] : __( 'N/A', 'woocommerce-square' );
|
416 |
+
|
417 |
+
$html .= sprintf(
|
418 |
+
'<td class="sv-wc-payment-gateway-payment-method-%1$s wc-%2$s-payment-method-%1$s" data-title="%4$s">%3$s</td>',
|
419 |
+
sanitize_html_class( $attribute ),
|
420 |
+
sanitize_html_class( $this->get_plugin()->get_id_dasherized() ),
|
421 |
+
$value,
|
422 |
+
esc_attr( $attribute_title )
|
423 |
+
);
|
424 |
+
}
|
425 |
+
|
426 |
+
$html .= '</tr>';
|
427 |
+
}
|
428 |
+
|
429 |
+
/**
|
430 |
+
* My Payment Methods Table Row HTML Filter.
|
431 |
+
*
|
432 |
+
* Allow actors to modify the table row HTML.
|
433 |
+
*
|
434 |
+
* @since 3.0.0
|
435 |
+
*
|
436 |
+
* @param string $html table row HTML
|
437 |
+
* @param Payment_Gateway_Payment_Token[] $tokens simple array of token objects
|
438 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
439 |
+
*/
|
440 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_row_html', $html, $tokens, $this );
|
441 |
+
}
|
442 |
+
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Return the payment method data for a given token
|
446 |
+
*
|
447 |
+
* @since 3.0.0
|
448 |
+
*
|
449 |
+
* @param Payment_Gateway_Payment_Token $token the token object
|
450 |
+
* @return array payment method data suitable for HTML output
|
451 |
+
*/
|
452 |
+
protected function get_table_body_row_data( $token ) {
|
453 |
+
|
454 |
+
$method = array(
|
455 |
+
'title' => $this->get_payment_method_title_html( $token ),
|
456 |
+
'default' => $this->get_payment_method_default_html( $token ),
|
457 |
+
'details' => $this->get_payment_method_details_html( $token ),
|
458 |
+
'actions' => $this->get_payment_method_actions_html( $token ),
|
459 |
+
);
|
460 |
+
|
461 |
+
// add the expiration date if applicable
|
462 |
+
if ( $token->get_exp_month() && $token->get_exp_year() ) {
|
463 |
+
$method['expiry'] = $this->get_payment_method_expiry_html( $token );
|
464 |
+
}
|
465 |
+
|
466 |
+
/**
|
467 |
+
* My Payment Methods Table Body Row Data Filter.
|
468 |
+
*
|
469 |
+
* Allow actors to modify the table body row data.
|
470 |
+
*
|
471 |
+
* @since 3.0.0
|
472 |
+
*
|
473 |
+
* @param array $methods {
|
474 |
+
* @type string $title payment method title
|
475 |
+
* @type string $expiry payment method expiry
|
476 |
+
* @type string $actions actions for payment method
|
477 |
+
* }
|
478 |
+
* @param array $token simple array of Payment_Gateway_Payment_Token objects
|
479 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
480 |
+
*/
|
481 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_body_row_data', $method, $token, $this );
|
482 |
+
}
|
483 |
+
|
484 |
+
/**
|
485 |
+
* Get a token's payment method title HTML.
|
486 |
+
*
|
487 |
+
* @since 3.0.0
|
488 |
+
*
|
489 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
490 |
+
* @return string
|
491 |
+
*/
|
492 |
+
protected function get_payment_method_title_html( Payment_Gateway_Payment_Token $token ) {
|
493 |
+
|
494 |
+
$nickname = $token->get_nickname();
|
495 |
+
$title = $token->get_nickname() ? $token->get_nickname() : $token->get_type_full();
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Filter a token's payment method title.
|
499 |
+
*
|
500 |
+
* @since 3.0.0
|
501 |
+
*
|
502 |
+
* @param string $title payment method title
|
503 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
504 |
+
*/
|
505 |
+
$title = apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_method_title', $title, $token, $this );
|
506 |
+
|
507 |
+
$html = '<div class="view">' . esc_html( $title ) . '</div>';
|
508 |
+
|
509 |
+
// add the edit context input
|
510 |
+
$html .= '<div class="edit" style="display:none;">';
|
511 |
+
$html .= '<input type="text" class="nickname" name="nickname" value="' . esc_html( $token->get_nickname() ) . '" placeholder="' . esc_attr( __( 'Nickname', 'woocommerce-square' ) ) . '" />';
|
512 |
+
$html .= '</div>';
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Filter a token's payment method title HTML.
|
516 |
+
*
|
517 |
+
* @since 3.0.0
|
518 |
+
*
|
519 |
+
* @param string $html title HTML
|
520 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
521 |
+
*/
|
522 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_method_title_html', $html, $token );
|
523 |
+
}
|
524 |
+
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Get a token's payment method "default" flag HTML.
|
528 |
+
*
|
529 |
+
* @since 3.0.0
|
530 |
+
*
|
531 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
532 |
+
* @return string
|
533 |
+
*/
|
534 |
+
protected function get_payment_method_default_html( Payment_Gateway_Payment_Token $token ) {
|
535 |
+
|
536 |
+
$html = '<div class="view">';
|
537 |
+
$html .= $token->is_default() ? '<mark class="default">' . esc_html__( 'Default', 'woocommerce-square' ) . '</mark>' : '';
|
538 |
+
$html .= '</div>';
|
539 |
+
|
540 |
+
// add the edit context input
|
541 |
+
$html .= '<div class="edit" style="display:none;">';
|
542 |
+
$html .= '<input type="checkbox" class="default" name="default" value="yes" ' . checked( true, $token->is_default(), false ) . ' />';
|
543 |
+
$html .= '</div>';
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Filter a token's payment method "default" flag HTML.
|
547 |
+
*
|
548 |
+
* @since 3.0.0
|
549 |
+
*
|
550 |
+
* @param string $html "default" flag HTML
|
551 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
552 |
+
*/
|
553 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_method_default_html', $html, $token );
|
554 |
+
}
|
555 |
+
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Gets a token's payment method details HTML.
|
559 |
+
*
|
560 |
+
* This includes the method type icon, last four digits, and "default"
|
561 |
+
* badge if applicable. Example:
|
562 |
+
*
|
563 |
+
* [icon] * * * 1234 [default]
|
564 |
+
*
|
565 |
+
* @since 3.0.0
|
566 |
+
*
|
567 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
568 |
+
* @return array
|
569 |
+
*/
|
570 |
+
protected function get_payment_method_details_html( Payment_Gateway_Payment_Token $token ) {
|
571 |
+
|
572 |
+
$html = '';
|
573 |
+
|
574 |
+
if ( $image_url = $token->get_image_url() ) {
|
575 |
+
$html .= sprintf( '<img src="%1$s" alt="%2$s" title="%2$s" width="40" height="25" />', esc_url( $image_url ), esc_attr( $token->get_type_full() ) );
|
576 |
+
}
|
577 |
+
|
578 |
+
if ( $last_four = $token->get_last_four() ) {
|
579 |
+
$html .= "• • • {$last_four}";
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Filters a token's payment method details HTML.
|
584 |
+
*
|
585 |
+
* @since 3.0.0
|
586 |
+
*
|
587 |
+
* @param string $html details HTML
|
588 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
589 |
+
*/
|
590 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_details_html', $html, $token );
|
591 |
+
}
|
592 |
+
|
593 |
+
|
594 |
+
/**
|
595 |
+
* Get a token's payment method expiration date HTML.
|
596 |
+
*
|
597 |
+
* @since 3.0.0
|
598 |
+
*
|
599 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
600 |
+
* @return string
|
601 |
+
*/
|
602 |
+
protected function get_payment_method_expiry_html( Payment_Gateway_Payment_Token $token ) {
|
603 |
+
|
604 |
+
$html = esc_html( $token->get_exp_date() );
|
605 |
+
|
606 |
+
// TODO: add edit support {CW 2018-01-30}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Filter a token's payment method expiration date HTML.
|
610 |
+
*
|
611 |
+
* @since 3.0.0
|
612 |
+
*
|
613 |
+
* @param string $html expiration date HTML
|
614 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
615 |
+
*/
|
616 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_method_expiry_html', $html, $token );
|
617 |
+
}
|
618 |
+
|
619 |
+
|
620 |
+
/**
|
621 |
+
* Get a token's payment method actions HTML.
|
622 |
+
*
|
623 |
+
* @since 3.0.0
|
624 |
+
*
|
625 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
626 |
+
* @return string
|
627 |
+
*/
|
628 |
+
protected function get_payment_method_actions_html( Payment_Gateway_Payment_Token $token ) {
|
629 |
+
|
630 |
+
$actions = array(
|
631 |
+
'<a href="#" class="edit-payment-method button">' . esc_html__( 'Edit', 'woocommerce-square' ) . '</a>',
|
632 |
+
'<a href="#" class="save-payment-method button" style="display:none">' . esc_html__( 'Save', 'woocommerce-square' ) . '</a>',
|
633 |
+
);
|
634 |
+
|
635 |
+
foreach ( $this->get_payment_method_actions( $token ) as $action => $details ) {
|
636 |
+
|
637 |
+
$classes = isset( $details['class'] ) ? (array) $details['class'] : array();
|
638 |
+
$attributes = isset( $details['attributes'] ) ? (array) $details['attributes'] : array();
|
639 |
+
|
640 |
+
$attributes['data-token-id'] = $token->get_id();
|
641 |
+
$attributes['data-action'] = $action;
|
642 |
+
|
643 |
+
// if the action has a tooltip set
|
644 |
+
if ( ! empty( $details['tip'] ) ) {
|
645 |
+
|
646 |
+
$classes[] = 'tip';
|
647 |
+
|
648 |
+
$attributes['title'] = $details['tip'];
|
649 |
+
}
|
650 |
+
|
651 |
+
// build the attributes
|
652 |
+
foreach ( $attributes as $attribute => $value ) {
|
653 |
+
$attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
|
654 |
+
unset( $attributes[ $attribute ] );
|
655 |
+
}
|
656 |
+
|
657 |
+
// build the button
|
658 |
+
$actions[] = sprintf(
|
659 |
+
( in_array( 'disabled', $classes, true ) ) ? '<a class="button %2$s" %3$s>%4$s</a>' : '<a href="%1$s" class="button %2$s" %3$s>%4$s</a>',
|
660 |
+
! empty( $details['url'] ) ? esc_url( $details['url'] ) : '#',
|
661 |
+
implode( ' ', array_map( 'sanitize_html_class', $classes ) ),
|
662 |
+
implode( ' ', $attributes ),
|
663 |
+
esc_html( $details['name'] )
|
664 |
+
);
|
665 |
+
}
|
666 |
+
|
667 |
+
$html = implode( '', $actions );
|
668 |
+
|
669 |
+
/**
|
670 |
+
* Filters a token's payment method actions HTML.
|
671 |
+
*
|
672 |
+
* @since 3.0.0
|
673 |
+
*
|
674 |
+
* @param string $html actions HTML
|
675 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
676 |
+
*/
|
677 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_actions_html', $html, $token );
|
678 |
+
}
|
679 |
+
|
680 |
+
|
681 |
+
/**
|
682 |
+
* Gets the actions for the given payment method token.
|
683 |
+
*
|
684 |
+
* @since 3.0.0
|
685 |
+
*
|
686 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
687 |
+
* @return array
|
688 |
+
*/
|
689 |
+
protected function get_payment_method_actions( $token ) {
|
690 |
+
|
691 |
+
$actions = array(
|
692 |
+
'delete' => __( 'Delete', 'woocommerce-square' ),
|
693 |
+
);
|
694 |
+
|
695 |
+
$plugin_slug = $this->get_plugin()->get_id_dasherized();
|
696 |
+
|
697 |
+
foreach ( $actions as $action => $label ) {
|
698 |
+
|
699 |
+
$url = add_query_arg( array(
|
700 |
+
"wc-{$plugin_slug}-token" => $token->get_id(),
|
701 |
+
"wc-{$plugin_slug}-action" => $action,
|
702 |
+
) );
|
703 |
+
|
704 |
+
$actions[ $action ] = array(
|
705 |
+
'name' => $label,
|
706 |
+
'url' => wp_nonce_url( $url, "wc-{$plugin_slug}-token-action" ),
|
707 |
+
'class' => "{$action}-payment-method",
|
708 |
+
);
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* My Payment Methods Table Method Actions Filter.
|
713 |
+
*
|
714 |
+
* Allow actors to modify the table method actions.
|
715 |
+
*
|
716 |
+
* @since 3.0.0
|
717 |
+
*
|
718 |
+
* @param $actions array {
|
719 |
+
* @type string $url action URL
|
720 |
+
* @type string $class action button class
|
721 |
+
* @type string $name action button name
|
722 |
+
* }
|
723 |
+
* @param Payment_Gateway_Payment_Token $token
|
724 |
+
* @param Payment_Gateway_My_Payment_Methods $this instance
|
725 |
+
*/
|
726 |
+
return apply_filters( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_table_method_actions', $actions, $token, $this );
|
727 |
+
}
|
728 |
+
|
729 |
+
|
730 |
+
/** Payment Method actions ************************************************/
|
731 |
+
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Saves a payment method via AJAX.
|
735 |
+
*
|
736 |
+
* @internal
|
737 |
+
*
|
738 |
+
* @since 3.0.0
|
739 |
+
*/
|
740 |
+
public function ajax_save_payment_method() {
|
741 |
+
|
742 |
+
check_ajax_referer( 'wc_' . $this->get_plugin()->get_id() . '_save_payment_method', 'nonce' );
|
743 |
+
|
744 |
+
try {
|
745 |
+
|
746 |
+
$this->load_tokens();
|
747 |
+
|
748 |
+
$token_id = Square_Helper::get_post( 'token_id' );
|
749 |
+
|
750 |
+
if ( empty( $this->tokens[ $token_id ] ) || ! $this->tokens[ $token_id ] instanceof Payment_Gateway_Payment_Token ) {
|
751 |
+
throw new \Exception( 'Invalid token ID' );
|
752 |
+
}
|
753 |
+
|
754 |
+
$user_id = get_current_user_id();
|
755 |
+
$token = $this->tokens[ $token_id ];
|
756 |
+
$gateway = $this->get_plugin()->get_gateway_from_token( $user_id, $token );
|
757 |
+
|
758 |
+
// bail if the gateway or token couldn't be found for this user
|
759 |
+
if ( ! $gateway || ! $gateway->get_payment_tokens_handler()->user_has_token( $user_id, $token ) ) {
|
760 |
+
throw new \Exception( 'Invalid token' );
|
761 |
+
}
|
762 |
+
|
763 |
+
$data = array();
|
764 |
+
|
765 |
+
parse_str( Square_Helper::get_post( 'data' ), $data );
|
766 |
+
|
767 |
+
// set the data
|
768 |
+
$token = $this->save_token_data( $token, $data );
|
769 |
+
|
770 |
+
// use the handler so other methods don't remain default
|
771 |
+
if ( $token->is_default() ) {
|
772 |
+
$gateway->get_payment_tokens_handler()->set_default_token( $user_id, $token );
|
773 |
+
}
|
774 |
+
|
775 |
+
// persist the data
|
776 |
+
$gateway->get_payment_tokens_handler()->update_token( $user_id, $token );
|
777 |
+
|
778 |
+
wp_send_json_success( array(
|
779 |
+
'html' => $this->get_table_body_row_html( array( $token ) ),
|
780 |
+
'is_default' => $token->is_default(),
|
781 |
+
'nonce' => wp_create_nonce( 'wc_' . $this->get_plugin()->get_id() . '_save_payment_method' ),
|
782 |
+
) );
|
783 |
+
|
784 |
+
} catch ( \Exception $e ) {
|
785 |
+
|
786 |
+
wp_send_json_error( $e->getMessage() );
|
787 |
+
}
|
788 |
+
}
|
789 |
+
|
790 |
+
|
791 |
+
/**
|
792 |
+
* Saves data to a token.
|
793 |
+
*
|
794 |
+
* Gateways can override this to set their own data if they add custom Edit
|
795 |
+
* fields. Note that this does not persist the data to the db, but only sets
|
796 |
+
* it for the object.
|
797 |
+
*
|
798 |
+
* @since 3.0.0
|
799 |
+
*
|
800 |
+
* @param Payment_Gateway_Payment_Token $token token object
|
801 |
+
* @param array $data {
|
802 |
+
* new data to store for the token
|
803 |
+
*
|
804 |
+
* @type string $nickname method nickname
|
805 |
+
* @type string $default whether the method should be set as default
|
806 |
+
* }
|
807 |
+
* @return Payment_Gateway_Payment_Token
|
808 |
+
*/
|
809 |
+
protected function save_token_data( Payment_Gateway_Payment_Token $token, array $data ) {
|
810 |
+
|
811 |
+
$raw_nickname = ! empty( $data['nickname'] ) ? $data['nickname'] : '';
|
812 |
+
$clean_nickname = wc_clean( $raw_nickname );
|
813 |
+
|
814 |
+
// only set the nickname if there is a clean value, or it was deliberately cleared
|
815 |
+
if ( $clean_nickname || ! $raw_nickname ) {
|
816 |
+
$token->set_nickname( $clean_nickname );
|
817 |
+
}
|
818 |
+
|
819 |
+
$token->set_default( isset( $data['default'] ) && 'yes' === $data['default'] );
|
820 |
+
|
821 |
+
return $token;
|
822 |
+
}
|
823 |
+
|
824 |
+
|
825 |
+
/**
|
826 |
+
* Handle payment methods actions, e.g. deleting a payment method or setting
|
827 |
+
* one as default
|
828 |
+
*
|
829 |
+
* @since 3.0.0
|
830 |
+
*/
|
831 |
+
public function handle_payment_method_actions() {
|
832 |
+
|
833 |
+
if ( ! $this->has_tokens ) {
|
834 |
+
return;
|
835 |
+
}
|
836 |
+
|
837 |
+
$token = isset( $_GET[ 'wc-' . $this->get_plugin()->get_id_dasherized() . '-token' ] ) ? trim( $_GET[ 'wc-' . $this->get_plugin()->get_id_dasherized() . '-token' ] ) : '';
|
838 |
+
$action = isset( $_GET[ 'wc-' . $this->get_plugin()->get_id_dasherized() . '-action' ] ) ? $_GET[ 'wc-' . $this->get_plugin()->get_id_dasherized() . '-action' ] : '';
|
839 |
+
|
840 |
+
// process payment method actions
|
841 |
+
if ( $token && $action && ! empty( $_GET['_wpnonce'] ) && is_user_logged_in() ) {
|
842 |
+
|
843 |
+
// security check
|
844 |
+
if ( false === wp_verify_nonce( $_GET['_wpnonce'], 'wc-' . $this->get_plugin()->get_id_dasherized() . '-token-action' ) ) {
|
845 |
+
|
846 |
+
Square_Helper::wc_add_notice( esc_html__( 'Oops, you took too long, please try again.', 'woocommerce-square' ), 'error' );
|
847 |
+
|
848 |
+
$this->redirect_to_my_account();
|
849 |
+
}
|
850 |
+
|
851 |
+
// current logged in user
|
852 |
+
$user_id = get_current_user_id();
|
853 |
+
|
854 |
+
$gateway = $this->get_plugin()->get_gateway_from_token( $user_id, $token );
|
855 |
+
|
856 |
+
// couldn't find an associated gateway for that token
|
857 |
+
if ( ! is_object( $gateway ) ) {
|
858 |
+
|
859 |
+
Square_Helper::wc_add_notice( esc_html__( 'There was an error with your request, please try again.', 'woocommerce-square' ), 'error' );
|
860 |
+
|
861 |
+
$this->redirect_to_my_account();
|
862 |
+
}
|
863 |
+
|
864 |
+
switch ( $action ) {
|
865 |
+
|
866 |
+
// handle deletion
|
867 |
+
case 'delete':
|
868 |
+
|
869 |
+
if ( ! $gateway->get_payment_tokens_handler()->remove_token( $user_id, $token ) ) {
|
870 |
+
|
871 |
+
/* translators: Payment method as in a specific credit card, e-check or bank account */
|
872 |
+
Square_Helper::wc_add_notice( esc_html__( 'Error removing payment method', 'woocommerce-square' ), 'error' );
|
873 |
+
|
874 |
+
} else {
|
875 |
+
|
876 |
+
/* translators: Payment method as in a specific credit card, e-check or bank account */
|
877 |
+
Square_Helper::wc_add_notice( esc_html__( 'Payment method deleted.', 'woocommerce-square' ) );
|
878 |
+
|
879 |
+
/**
|
880 |
+
* Fires after a new payment method is deleted by a customer.
|
881 |
+
*
|
882 |
+
* @since 3.0.0
|
883 |
+
*
|
884 |
+
* @param string $token_id ID of the deleted token
|
885 |
+
* @param int $user_id user ID
|
886 |
+
*/
|
887 |
+
do_action( 'wc_payment_gateway_' . $gateway->get_id() . '_payment_method_deleted', $token, $user_id );
|
888 |
+
}
|
889 |
+
|
890 |
+
break;
|
891 |
+
|
892 |
+
// custom actions
|
893 |
+
default:
|
894 |
+
|
895 |
+
/**
|
896 |
+
* My Payment Methods Custom Action.
|
897 |
+
*
|
898 |
+
* Fired when a custom action is requested for a payment method (e.g. other than delete/make default)
|
899 |
+
*
|
900 |
+
* @since 3.0.0
|
901 |
+
* @param \Payment_Gateway_My_Payment_Methods $this instance
|
902 |
+
*/
|
903 |
+
do_action( 'wc_' . $this->get_plugin()->get_id() . '_my_payment_methods_action_' . sanitize_title( $action ), $this );
|
904 |
+
break;
|
905 |
+
}
|
906 |
+
|
907 |
+
$this->redirect_to_my_account();
|
908 |
+
}
|
909 |
+
}
|
910 |
+
|
911 |
+
|
912 |
+
/**
|
913 |
+
* Redirect back to the Payment Methods (WC 2.6+) or My Account page
|
914 |
+
*
|
915 |
+
* @since 3.0.0
|
916 |
+
*/
|
917 |
+
protected function redirect_to_my_account() {
|
918 |
+
|
919 |
+
wp_redirect( wc_get_account_endpoint_url( 'payment-methods' ) );
|
920 |
+
exit;
|
921 |
+
}
|
922 |
+
|
923 |
+
|
924 |
+
/**
|
925 |
+
* Return the gateway plugin, primarily a convenience method to other actors
|
926 |
+
* using filters
|
927 |
+
*
|
928 |
+
* @since 3.0.0
|
929 |
+
*
|
930 |
+
* @return Payment_Gateway_Plugin
|
931 |
+
*
|