| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <?php
- declare(strict_types=1);
- namespace SixShop\Lakala;
- use SixShop\Lakala\Dto\LocationInfo;
- use SixShop\Lakala\Facade\TransactionService;
- use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaAccBusiFields;
- use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaDetail;
- use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaGoodsDetail;
- use SixShop\Payment\Contracts\PaymentNotifyResult;
- use SixShop\Payment\Contracts\PaymentProviderInterface;
- use SixShop\Payment\Contracts\PaymentQueryResult;
- use SixShop\Payment\Contracts\PaymentRefundRequest;
- use SixShop\Payment\Contracts\PaymentRefundResult;
- use SixShop\Payment\Contracts\PaymentResponse;
- use SixShop\Payment\Entity\ExtensionPaymentEntity;
- use SixShop\Payment\Enum\PaymentBizEnum;
- use SixShop\Payment\Enum\PaymentStatusEnum;
- use SixShop\Payment\Event\PaymentSuccessEvent;
- use think\facade\Event;
- class PaymentProvider implements PaymentProviderInterface
- {
- public function __construct(
- private readonly Config $config,
- private readonly ExtensionPaymentEntity $extensionPaymentEntity,
- )
- {
- }
- #[\Override] public function create(array $order, PaymentBizEnum $bizType): PaymentResponse
- {
- $payment = $this->extensionPaymentEntity->where([
- 'order_id' => $order['id'],
- 'pay_type' => Extension::EXTENSION_ID,
- 'biz_type' => $bizType,
- ])->findOrEmpty();
- if (!$payment->isEmpty()) {
- // todo 判断订单是否支付成功
- // 支付时间结束关闭订单
- // 订单未支付可重新支付
- // 交易已关闭请重新下单
- //订单已付款请勿重复操作
- // 订单已退款请重新下单
- //订单已撤销请重新下单
- // 订单支付中请稍后再试
- // 订单支付失败请重新下单
- throw new \RuntimeException('开发测试中,请稍后再试');
- }
- $payment->transaction(function () use ($bizType, $order, $payment) {
- $randomDiscount = mt_rand(0, intval($this->config->random_discount_max * 100)) / 100;
- $order['pay_amount'] = $order['pay_amount'] - $randomDiscount;
- $order['pay_amount'] = max(0.01, round($order['pay_amount'], 2));
- $payment->save([
- 'user_id' => $order['user_id'],
- 'order_id' => $order['id'],
- 'order_sn' => $order['order_sn'],
- 'biz_type' => $bizType,
- 'pay_type' => Extension::EXTENSION_ID,
- 'amount' => $order['pay_amount'],
- 'status' => PaymentStatusEnum::PENDING
- ]);
- $expireDuration = 15; // 分钟
- $payment->expire_time = time() + $expireDuration * 60;
- $payment->payment_param = $this->createPaymentParam($order, $payment, $expireDuration);
- $payment->transaction_id = $payment->payment_param->trade_no;
- $payment->save();
- });
- return new PaymentResponse(orderNo: $payment->out_trade_no, type: Extension::EXTENSION_ID, raw: $payment->toArray());
- }
- #[\Override] public function notify(array $request): PaymentNotifyResult
- {
- throw new \Exception('Not implemented');
- }
- #[\Override] public function query(int $recordID): PaymentQueryResult
- {
- $payment = $this->extensionPaymentEntity->read($recordID);
- if ($payment->status === PaymentStatusEnum::PENDING) {
- $response = TransactionService::queryTrade($payment->transaction_id);
- // INIT-初始化 CREATE-下单成功 SUCCESS-交易成功 FAIL-交易失败 DEAL-交易处理中 UNKNOWN-未知状态 CLOSE-订单关闭 PART_REFUND-部分退款 REFUND-全部退款(或订单被撤销)
- $payment->status = match ($response->trade_state) {
- 'DEAL' => PaymentStatusEnum::PENDING,
- 'SUCCESS' => PaymentStatusEnum::SUCCESS,
- 'FAIL' => PaymentStatusEnum::FAIL,
- 'CLOSE' => PaymentStatusEnum::CLOSED,
- default => PaymentStatusEnum::PENDING,
- };
- if ($payment->status !== PaymentStatusEnum::PENDING) {
- $payment->status_desc = $response->trade_state_desc;
- $payment->payment_result = $response;
- if ($payment->status === PaymentStatusEnum::SUCCESS) {
- $payment->payment_time = time();
- $payment->save();
- Event::trigger(new PaymentSuccessEvent($payment['order_sn'], Extension::EXTENSION_ID, $payment->toArray(), $payment->biz_type));
- } else {
- $payment->save();
- }
- }
- }
- return new PaymentQueryResult(
- orderNo: $payment['out_trade_no'],
- status: $payment['status'],
- amount: (float)$payment['amount'],
- raw: $payment->toArray()
- );
- }
- #[\Override] public function refund(int $recordID, PaymentRefundRequest $param): PaymentRefundResult
- {
- throw new \Exception('Not implemented');
- }
- #[\Override] public function refundQuery(int $refundID): PaymentRefundResult
- {
- throw new \Exception('Not implemented');
- }
- private function createPaymentParam(array $order, ExtensionPaymentEntity $payment, int $expireDuration): object
- {
- $accBusiFields = new TradePreorderWechaAccBusiFields();
- $accBusiFields->setTimeoutExpress($expireDuration);
- $accBusiFields->setSubAppid($this->config->sub_appid);
- $accBusiFields->setUserId($order['params']['openid']);
- /*$detail = new TradePreorderWechaDetail();
- $detail->setCostPrice((float)$order['pay_amount']);
- $detail->setReceiptId('');
- $goodsDetailList = [];
- foreach ($order['order_goods'] as $goods) {
- $goodsDetail = new TradePreorderWechaGoodsDetail();
- $goodsDetail->setGoodsId((string)$goods['goods_id']);
- $goodsDetail->setQuantity($goods['num']);
- $goodsDetail->setWxpayGoodsId('');
- $goodsDetail->setPrice(round($goods['price']*100, 0));
- $goodsDetail->setGoodsName($goods['goods_name']);
- $goodsDetailList[] = $goodsDetail;
- }
- $detail->setGoodsDetail($goodsDetailList);
- $accBusiFields->setDetail($detail);*/
- return TransactionService::preOrder(
- outTradeNo: $payment['out_trade_no'],
- totalAmount: $payment['amount'],
- locationInfo: new LocationInfo(requestIP: $order['params']['ip']),
- subject: '订单:' . $order['order_sn'],
- settleType: '1', // 拉卡拉分账
- remark: $order['description'],
- accBusiFields: $accBusiFields,
- );
- }
- }
|