symfony - Sylius:传递给 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)。
条带支付时出现BUG,显示金额对应初始金额,不支持礼品卡减免(截图3)
解决方案
如果您正在使用此 Sylius 插件:flux-se/sylius-payum-stripe-plugin
您必须创建代表您的礼品卡装饰的单独优惠券:https ://github.com/FLUX-SE/SyliusPayumStripePlugin/blob/master/src/Provider/DetailsProvider.php新的数组成员creatediscounts
就像 Stripe 文档定义它一样:https ://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-discounts
该插件仅处理链接到一个OrderItem
或一个的默认 Sylius 调整OrderItemUnit
。如果调整是链接到的,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
推荐阅读
- python - 并行执行 - Spark
- php - 如何在 PHP 中“作为 JSON”读取抓取的 JavaScript 对象文字(带有不带引号的键)?
- google-maps - 如何去除地图上的标记
- css - 渲染时使用样式的边框属性会消耗更多内存?
- spring - 如何为 Spring 消息传递、Web 套接字 @DestinationVariable 或 jms @Header 注册自定义转换器
- sql - SQL 注入问题 - 缺少页码
- android - 未在 Play Store 中显示更新的 apk
- c# - 如何在 LINQ 中获取和使用分组源?
- asp.net-mvc - ASP.NET 从标签调用 #id
- nonetype - None 关键字参数如何转换为 int 数据类型?