🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
要在 Magento 2 中添加新的支付选项,您需要构建一个自定义支付模块,在结账时呈现支付方式,并将模块配置为与 Magento 的系统一起处理支付数据。 Magento是一个灵活的开源平台,无需修改本机Magento代码。根据现有的Magento结账模块,将自定义付款方式创建为单独的模块。 步骤1:在Magento中注册支付模块 创建注册文件registration.php在支付模块根目录下。在本例中,文件路径为app/code/CCBill/CustomPaymentOption/registration.php。 添加以下代码以在Magento系统中注册模块(组件): ``` <?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'CCBill_CustomPaymentOption', __DIR__ ); ``` 编辑供应商(CCBill)和模块名称(CustomPaymentOption),以匹配您的模块名称。 步骤2:声明支付模块名称 访问自定义模块的app/code/CCBill/CustomPaymentOption/etc/目录并创建一个模块文件module.xml。在模块文件module.xml内定义模块名称: ``` <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="CCBill_ CustomPaymentOption" setup_version="2.2.0"> <sequence> <module name="Magento_Sales"/> <module name="Magento_Payment"/> <module name="Magento_Checkout"/> </sequence> </module> </config> <sequence> ``` 标签控制加载顺序,并确保系统在自定义支付模块之前加载列出的组件。 步骤3:添加付款方式配置设置 在Magento管理中配置和显示付款方式通过创建system.xml文件。在app/code/CCBill/CustomPaymentOption/etc/adminhtml/目录下,创建system.xml文件并添加以下代码: ``` <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <section id="payment"> <group id="ccbill_custompaymentoption" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Custom Payment Option</label> <field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Enabled</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> <field id="title" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Title</label> </field> <field id="cctypes" translate="label" type="multiselect" sortOrder="75" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Credit Card Types</label> <source_model>Magento\Payment\Model\Source\Cctype</source_model> </field> </group> </section> </system> </config> ``` 步骤4:添加默认系统配置值 定义system.xml的默认值。通过创建配置文件config.xml。创建配置文件config.xml,并添加以下代码: ``` <?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> <default> <payment> <ccbill_custompaymentoption> <title>Custom Payment Option</title> <active>1</active> <payment_action>preferred_method</payment_action> <model>CCBill\CustomPaymentOption\Model\PaymenMethod</model> <order_status>pending_payment</order_status> </ccbill_custompaymentoption> </payment> </default> </config> ``` 步骤5:创建付款方式模型 访问app/code/CCBill/CustomPaymentOption/Model/目录并创建CustomPaymmentOption.php文件。复制以下代码以在.php文件中建立支付方法模型类 ``` <?php namespace CCBill\CustomPaymentOption\Model; class CustomPaymentOption extends \Magento\Payment\Model\Method\Cc { const METHOD_CODE = 'ccbill_custompaymentoption'; protected $_code = self::METHOD_CODE; protected $_custompayments; protected $_isGateway = true; protected $_canCapture = true; protected $_canCapturePartial = true; protected $_canRefund = true; protected $_minOrderTotal = 0; protected $_supportedCurrencyCodes = array('USD','GBP','EUR'); public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, \Magento\Payment\Helper\Data $paymentData, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Payment\Model\Method\Logger $logger, \Magento\Framework\Module\ModuleListInterface $moduleList, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Extension\Extension $Extension, array $data = array() ) { parent::__construct( $context, $registry, $extensionFactory, $customAttributeFactory, $paymentData, $scopeConfig, $logger, $moduleList, $localeDate, null, null, $data ); $this->_code = 'Extension'; $this->_Extension = $Extension; $this->_Extension->setApiKey($this->getConfigData('api_key')); $this->_minOrderTotal = $this->getConfigData('min_order_total'); } public function canUseForCurrency($currencyCode) { if (!in_array($currencyCode, $this->_supportedCurrencyCodes)) { return false; } return true; } public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) { $order = $payment->getOrder(); $billing = $order->getBillingAddress(); try{ $charge = \Extension\Charge::create(array( 'amount' => $amount*100, 'currency' => strtolower($order->getBaseCurrencyCode()), 'card' => array( 'number' => $payment->getCcNumber(), 'exp_month' => sprintf('%02d',$payment->getCcExpMonth()), 'exp_year' => $payment->getCcExpYear(), 'cvc' => $payment->getCcCid(), 'name' => $billing->getName(), 'address_line1' => $billing->getStreet(1), 'address_line2' => $billing->getStreet(2), 'address_zip' => $billing->getPostcode(), 'address_state' => $billing->getRegion(), 'address_country' => $billing->getCountry(), ), 'description' => sprintf('#%s, %s', $order->getIncrementId(), $order->getCustomerEmail()) )); $payment->setTransactionId($charge->id)->setIsTransactionClosed(0); return $this; }catch (\Exception $e){ $this->debugData(['exception' => $e->getMessage()]); throw new \Magento\Framework\Validator\Exception(__('Payment capturing error.')); } } public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount) { $transactionId = $payment->getParentTransactionId(); try { \Extension\Charge::retrieve($transactionId)->refund(); } catch (\Exception $e) { $this->debugData(['exception' => $e->getMessage()]); throw new \Magento\Framework\Validator\Exception(__('Payment refunding error.')); } $payment ->setTransactionId($transactionId . '-' . \Magento\Sales\Model\Order\Payment\Transaction::TYPE_REFUND) ->setParentTransactionId($transactionId) ->setIsTransactionClosed(1) ->setShouldCloseParentTransaction(1); return $this; } public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null){ $this->_minOrderTotal = $this->getConfigData('min_order_total'); if($quote && $quote->getBaseGrandTotal() < $this->_minOrderTotal) { return false; } return $this->getConfigData('api_key', ($quote ? $quote->getStoreId() : null)) && parent::isAvailable($quote); } } ``` 要检查新的付款方式是否可用,请访问Magento管理并进入商店>配置。展开“销售”下拉列表并打开“付款方式”菜单。确认设置system.xml与配置config.xml中定义的值一致。 步骤6:配置依赖注入 要将自定义付款方法注入现有的MagentoCcGenericConfigProvider中,请创建新的di.xml文件,放置di.xml在app/code/CCBill/CustomPaymentOption/etc/frontend/目录下,并将付款方式代码作为参数添加: ``` <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Payment\Model\CcGenericConfigProvider"> <arguments> <argument name="methodCodes" xsi:type="array"> <item name="CustomPaymentOption" xsi:type="const">CCBill\CustomPaymentOption\Model\Payment::METHOD_CODE</item> </argument> </arguments> </type> </config> ``` 配置支付方式模块后,系统需要在商店前端呈现用户界面。 步骤7:添加付款方式渲染器 创建custompayments.js文件在app/code/CCBill/CustomPaymentOption/view/frontend/web/js/view/payment/目录下。添加以下代码: ``` define( [ 'uiComponent', 'Magento_Checkout/js/model/payment/renderer-list' ], function ( Component, rendererList ) { 'use strict'; rendererList.push( { type: 'ccbill_custompaymentopyion', component: 'CCBill_CustomPaymentOption/js/view/payment/method-renderer/custompayments' } ); ``` 本例中.js文件的主要功能是添加支付方法渲染器。 步骤8:向渲染器声明付款方法 在app/code/CCBill/CustomPaymentOption/view/frontend/web/js/view/payment/method-renderer/目录中创建一个.js文件。使用以下代码控制新支付方法的前端逻辑: ``` define( [ 'Magento_Payment/js/view/payment/cc-form', 'jquery', 'Magento_Checkout/js/action/place-order', 'Magento_Checkout/js/model/full-screen-loader', 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Payment/js/model/credit-card-validation/validator' ], function (Component, $) { 'use strict'; return Component.extend({ defaults: { template: 'CCBill_CustomPaymentOption/payment/custompayments' }, getCode: function() { return 'ccbill_custompaymentoption'; }, isActive: function() { return true; }, validate: function() { var $form = $('#' + this.getCode() + '-form'); return $form.validation() && $form.validation('isValid'); } }); } ); ``` 步骤9:创建付款方式模板 系统使用Knockout JavaScript框架呈现UI组件。构建包含标题、账单地址和付款方法单选按钮的模板。 在app/code/CCBill/CustomPaymentOption/view/frontend/web/js/view/payment/目录中创建.html文件。 ``` <div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}"> <div class="payment-method-title field choice"> <input type="radio" name="payment[method]" class="radio" data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/> <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label> </div> <div class="payment-method-content"> <!-- ko foreach: getRegion('messages') --> <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> <div class="payment-method-billing-address"> <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) --> <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> </div> <form class="form" data-bind="attr: {'id': getCode() + '-form'}"> <!-- ko template: 'Magento_Payment/payment/cc-form' --><!-- /ko --> </form> <div class="checkout-agreements-block"> <!-- ko foreach: $parent.getRegion('before-place-order') --> <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> </div> <div class="actions-toolbar"> <div class="primary"> <button class="action primary checkout" type="submit" data-bind=" click: placeOrder, attr: {title: $t('Place Order')}, css: {disabled: !isPlaceOrderActionAllowed()}, enable: (getCode() == isChecked()) " disabled> <span data-bind="text: $t('Place Order')"></span> </button> </div> </div> </div> </div> ``` 为方便起见,请使用现有Magento支付模块中的模板,.html模板位于<random_module>/frontend/web/template/payment/paymentmodule目录下。 步骤10:在结账时显示付款方式 要在结账页面上显示付款方式,请创建checkout_index_index.xml在app/code/CCBill/CustomPaymentOption/view/frontend/layout/目录下。 ``` <?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="checkout.root"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="children" xsi:type="array"> <item name="steps" xsi:type="array"> <item name="children" xsi:type="array"> <item name="billing-step" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <item name="payment" xsi:type="array"> <item name="children" xsi:type="array"> <item name="renders" xsi:type="array"> <!-- merge payment method renders here --> <item name="children" xsi:type="array"> <item name="paymentoptions-payments" xsi:type="array"> <item name="component" xsi:type="string">CCBill_CustomPaymentOption/js/view/payment/paymentoptions</item> <item name="methods" xsi:type="array"> <item name="CustomPaymentOptions" xsi:type="array"> <item name="isBillingAddressRequired" xsi:type="boolean">true</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </argument> </arguments> </referenceBlock> </body> </page> ```