Skip to content
intermediate Phase 47 · Checkout Advanced

Payment Methods

Payment method interface, authorize/capture/void operations, payment configuration, and custom payment implementation

1h
0 problems
Topic Progress 0%

Payment Method Interface

Payment Method Interface

// Magento\Payment\Api\PaymentMethodInterface
namespace Magento\Payment\Api;

interface PaymentMethodInterface
{
    /**
     * Get payment method code
     */
    public function getCode(): string;

    /**
     * Get payment method title
     */
    public function getTitle(): string;

    /**
     * Check if method is available
     */
    public function isAvailable(
        \Magento\Quote\Api\Data\CartInterface $quote = null
    ): bool;
}

Payment Information Interface

// Magento\Payment\Api\Data\PaymentInterface
namespace Magento\Payment\Api\Data;

interface PaymentInterface
{
    public function getMethod(): string;
    public function getPoNumber(): ?string;
    public function getAdditionalData(): ?array;
    public function get_cc_cid(): ?string;
    public function get_cc_exp_month(): ?string;
    public function get_cc_exp_year(): ?string;
    public function get_cc_number(): ?string;
    public function get_cc_type(): ?string;
}

Authorize, Capture, Void

Payment Action Types

// Magento\Payment\Model\Method\AbstractMethod
namespace Magento\Payment\Model\Method;

class AbstractMethod implements \Magento\Payment\Api\PaymentMethodInterface
{
    /**
     * Payment action constants
     */
    const ACTION_AUTHORIZE = 'authorize';
    const ACTION_AUTHORIZE_CAPTURE = 'authorize_capture';
    const ACTION_ORDER = 'order';

    /**
     * Authorize - verify funds, hold amount
     */
    public function authorize(
        \Magento\Payment\Api\Data\PaymentInterface $payment,
        float $amount
    ): self {
        // Call gateway to authorize
        $this->gateway->authorize($payment, $amount);

        $payment->setAuthorizationTransaction(
            $gatewayResponse->getTransactionId()
        );

        return $this;
    }

    /**
     * Capture - collect funds (requires authorization first)
     */
    public function capture(
        \Magento\Payment\Api\Data\PaymentInterface $payment,
        float $amount
    ): self {
        $this->gateway->capture($payment, $amount);

        $payment->setCaptureTransaction(
            $gatewayResponse->getTransactionId()
        );

        return $this;
    }

    /**
     * Void - cancel authorization
     */
    public function void(
        \Magento\Payment\Api\Data\PaymentInterface $payment
    ): self {
        $this->gateway->void($payment);

        $payment->setIsTransactionClosed(true);

        return $this;
    }
}

Payment Flow Examples

// Authorization only flow
$payment->authorize($paymentInfo, $amount);
// Funds are held but not captured

// Authorize + Capture flow
$payment->order($paymentInfo, $amount);
// Funds are captured immediately

// Void (cancel) flow
$payment->void($paymentInfo);
// Authorization is cancelled

Payment Configuration

System.xml Configuration

<!-- app/code/Vendor/Payment/etc/system.xml -->
<config>
    <section id="payment">
        <group id="custom_payment" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Custom Payment</label>
            <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1">
                <label>Enabled</label>
                <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
            </field>
            <field id="title" translate="label" type="text" sortOrder="10" showInDefault="1">
                <label>Title</label>
            </field>
            <field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1">
                <label>New Order Status</label>
                <source_model>Magento\Sales\Model\Config\Source\Order\Status\Newprocessing</source_model>
            </field>
            <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1">
                <label>Payment Action</label>
                <source_model>Magento\Payment\Model\Config\Source\Action\Order</source_model>
            </field>
            <field id="allowspecific" translate="label" type="select" sortOrder="40" showInDefault="1">
                <label>Payment from Applicable Countries</label>
                <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
            </field>
        </group>
    </section>
</config>

Config Provider

namespace Vendor\Payment\Model\ConfigProvider;

class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
{
    public function getConfig(): array
    {
        return [
            'payment' => [
                'custom_payment' => [
                    'title' => $this->getConfigData('title'),
                    'order_status' => $this->getConfigData('order_status'),
                    'payment_action' => $this->getConfigData('payment_action'),
                ],
            ],
        ];
    }
}

Custom Payment Implementation

Custom Payment Method

namespace Vendor\Payment\Model\Method;

class Custom extends \Magento\Payment\Model\Method\AbstractMethod
{
    protected $_code = 'custom_payment';
    protected $_isGateway = true;
    protected $_canAuthorize = true;
    protected $_canCapture = true;
    protected $_canVoid = true;
    protected $_canRefund = true;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Payment\Model\Method\Logger $logger,
        private GatewayInterface $gateway
    ) {
        parent::__construct($scopeConfig, $logger);
    }

    public function authorize(
        \Magento\Payment\Api\Data\PaymentInterface $payment,
        float $amount
    ): \Magento\Payment\Model\Method\AbstractMethod {
        $transactionId = $this->gateway->authorize([
            'amount' => $amount,
            'currency' => $payment->getOrder()->getCurrencyCode(),
            'card_number' => $payment->getCcNumber(),
            'card_expiry' => $payment->getCcExpMonth() . '/' . $payment->getCcExpYear(),
            'card_cvv' => $payment->getCcCid(),
        ]);

        $payment->setAuthorizationTransaction($transactionId);
        $payment->setIsTransactionClosed(false);

        return $this;
    }

    public function capture(
        \Magento\Payment\Api\Data\PaymentInterface $payment,
        float $amount
    ): \Magento\Payment\Model\Method\AbstractMethod {
        $transactionId = $this->gateway->capture([
            'authorization_id' => $payment->getAuthorizationTransaction(),
            'amount' => $amount,
        ]);

        $payment->setCaptureTransaction($transactionId);
        $payment->setIsTransactionClosed(true);

        return $this;
    }
}

Payment Gateway Interface

namespace Vendor\Payment\Gateway;

interface GatewayInterface
{
    public function authorize(array $request): string;
    public function capture(array $request): string;
    public function void(string $transactionId): void;
    public function refund(array $request): string;
}

Quiz

1. What is the difference between authorize and capture?

Question 1 options

2. What does payment_action configuration control?

Question 2 options

3. What must a payment method implement to be refundable?

Question 3 options

Flashcards

Question

What does authorize() do?

Answer

Verifies and holds funds without collecting them

Question

What does capture() do?

Answer

Collects previously authorized funds

Question

payment_action options?

Answer

authorize (hold only) or authorize_capture (hold + collect)

Question

Minimum payment method flags?

Answer

_canAuthorize, _canCapture, _canVoid, _canRefund

Revision Notes

Key Takeaways

  • 1. Payment methods implement PaymentMethodInterface for availability checks
  • 2. Authorize holds funds, capture collects them, void cancels authorization
  • 3. system.xml configures payment settings in admin
  • 4. ConfigProvider supplies payment config to checkout JavaScript
  • 5. Custom payment requires gateway interface and method class

Interview Tips

  • Explain the authorize → capture → void payment lifecycle
  • Discuss when to use authorize-only vs authorize-capture
  • Describe how payment config flows from system.xml to checkout JS

Cheat Sheet

Payment Methods:
  authorize()  → hold funds
  capture()    → collect funds
  void()       → cancel hold
  refund()     → return funds

Flags:
  _canAuthorize, _canCapture, _canVoid, _canRefund

Config:
  system.xml → admin settings
  ConfigProvider → JS config
  di.xml → method registration