Sylius:传递给 Stripe 的总订单金额错误

Sylius : Wrong total order amount passed to Stripe

我添加了一个可以计算礼品卡金额的新处理器。

services:
    app.order_processing.gift_card_processor:
        class: App\OrderProcessing\GiftCardProcessor
        arguments:
            - '@sylius.factory.adjustment'
            - '@translator'
        tags:
            - { name: sylius.order_processor, priority: 5 }

<?php

declare(strict_types=1);

namespace App\OrderProcessing;

use App\Entity\Order\Adjustment;
use App\Entity\Order\Order;
use Sylius\Component\Order\Model\OrderInterface as BaseOrderInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Webmozart\Assert\Assert;

final class GiftCardProcessor implements OrderProcessorInterface
{
    private FactoryInterface $adjustmentFactory;

    private TranslatorInterface $translator;

    public function __construct(
        FactoryInterface $adjustmentFactory,
        TranslatorInterface $translator
    ) {
        $this->adjustmentFactory = $adjustmentFactory;
        $this->translator = $translator;
    }

    public function process(BaseOrderInterface $order): void
    {
        /** @var Order $order */
        Assert::isInstanceOf($order, Order::class);

        // Remove all gift card adjustments, we recalculate everything from scratch.
        $order->removeAdjustments(Adjustment::ORDER_GIFT_CARD_ADJUSTMENT);

        foreach ($order->getGiftCardOrders() as $giftCardOrder) {
            $giftCard = $giftCardOrder->getGiftCard();
            $giftCardRemainingAmount = (int) $giftCard->getRemainingAmount() * 100;

            $amount = $giftCardRemainingAmount > $order->getTotal() ? $order->getTotal() : $giftCardRemainingAmount;

            /** @var Adjustment $adjustment */
            $adjustment = $this->adjustmentFactory->createNew();
            $adjustment->setType(Adjustment::ORDER_GIFT_CARD_ADJUSTMENT);
            $adjustment->setAmount(-$amount);
            $adjustment->setLabel($this->translator->trans('gift_card.ui.gift_card'));

            $giftCard->addAdjustment($adjustment);

            $giftCardOrder->setAmount($amount / 100);

            $order->addAdjustment($adjustment);
        }
    }
}

购物车中显示并插入数据库中的总订单金额是正确的(屏幕截图 1 和 2)

SCREENSHOT 1 SCREENSHOT 2

stripe支付出现bug,显示金额为初始金额,不支持礼品卡减值(截图3)

SCREENSHOT 3

如果您使用此 Sylius 插件:flux-se/sylius-payum-stripe-plugin 您必须创建代表您的礼品卡装饰的个人优惠券:https://github.com/FLUX-SE/SyliusPayumStripePlugin/blob/master/src/Provider/DetailsProvider.php the new array member to create is the discounts like the Stripe doc is defining it : https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-discounts

该插件仅处理链接到 OrderItemOrderItemUnit 的默认 Sylius 调整。如果调整链接在 Order 上,那么它不会被考虑在内,因为 Stripe 只是将所有 line_item 的总和作为总数。 Stripe 不允许订单项的金额为负数,这就是为什么优惠券是减少付款总额的唯一方法。

如果您使用此格式标记优惠券 ID,这是处理优惠券创建所需的 payum 扩展 sprintf('GIFT_CARD_%s', $giftCard->getCode()) :

<?php

declare(strict_types=1);

namespace App\GiftCard\Payum\Extension;

use FluxSE\PayumStripe\Request\Api\Resource\CreateCoupon;
use FluxSE\PayumStripe\Request\Api\Resource\RetrieveCoupon;
use FluxSE\SyliusPayumStripePlugin\Action\ConvertPaymentAction;
use Payum\Core\Extension\Context;
use Payum\Core\Extension\ExtensionInterface;
use Payum\Core\Request\Convert;
use Stripe\Exception\ApiErrorException;
use Sylius\Component\Core\Model\PaymentInterface;

final class CheckCouponsExtension implements ExtensionInterface
{
    public function onPreExecute(Context $context)
    {
    }

    public function onExecute(Context $context)
    {
    }

    public function onPostExecute(Context $context)
    {
        if ($context->getException()) {
            return;
        }

        if (false === $context->getAction() instanceof ConvertPaymentAction) {
            return;
        }

        /** @var mixed|Convert $request */
        $request = $context->getRequest();
        if (false === $request instanceof Convert) {
            return;
        }

        /** @var mixed|PaymentInterface $payment */
        $payment = $request->getSource();
        if (false === $payment instanceof PaymentInterface) {
            return;
        }

        $order = $payment->getOrder();
        if (null === $order) {
            return;
        }

        $gateway = $context->getGateway();
        foreach ($order->getGiftCardOrders() as $giftCardOrder) {
            $giftCard = $giftCardOrder->getGiftCard();
            $couponId = sprintf('GIFT_CARD_%s', $giftCard->getCode());
            $retrieveCouponRequest = new RetrieveCoupon($couponId);
            try {
                $gateway->execute($retrieveCouponRequest);
            } catch (ApiErrorException $e) {
                $createCouponRequest = new CreateCoupon([
                    'id' => $couponId,
                    "amount_off" => $giftCard->getAmount()/100,
                    "currency" => $order->getCurrencyCode(),
                    "metadata" => [
                        'SYLIUS_GIFTCARD_ID' => $giftCard->getId(),
                        'SYLIUS_GIFTCARD_CODE' => $giftCard->getCode(),
                    ],
                    "name" => sprintf("Gift card #%d", $giftCard->getId()),
                ]);
                $gateway->execute($createCouponRequest);
            }
        }
    }
}

这是服务声明:

services:
  App\GiftCard\Payum\Extension\CheckCouponsExtension:
    public: true
    tags:
      - name: payum.extension
        alias: app.extension.check_coupons
        factory: stripe_checkout_session