|
|
@@ -674,4 +674,146 @@ class OrderService extends AlibabaAgentBaseService
|
|
674
|
674
|
'reasons' => $reasons,
|
|
675
|
675
|
];
|
|
676
|
676
|
}
|
|
|
677
|
+
|
|
|
678
|
+ /**
|
|
|
679
|
+ * 提交售后申请
|
|
|
680
|
+ *
|
|
|
681
|
+ * API: com.alibaba.trade:alibaba.trade.createRefund-1
|
|
|
682
|
+ *
|
|
|
683
|
+ * 接口文档: https://open.1688.com/api/apidocdetail.htm?id=com.alibaba.trade%3Aalibaba.trade.createRefund-1
|
|
|
684
|
+ *
|
|
|
685
|
+ * 请求参数:
|
|
|
686
|
+ * - orderId: 主订单ID(必填)
|
|
|
687
|
+ * - orderEntryIds: 子订单ID列表,格式 "[123,456]"(必填)
|
|
|
688
|
+ * - disputeReasonId: 退款原因ID(必填,从 getRefundReasonList 获取)
|
|
|
689
|
+ * - description: 退款说明(必填)
|
|
|
690
|
+ * - goodsStatus: 货物状态(必填)
|
|
|
691
|
+ * - applyPayment: 退款金额,单位分(必填)
|
|
|
692
|
+ * - applyCarriage: 退运费,单位分(可选,默认0)
|
|
|
693
|
+ * - voucher: 凭证图片列表,格式 "[{url:'http://...'}]"(可选)
|
|
|
694
|
+ * - applyReason: 退款原因描述(可选)
|
|
|
695
|
+ *
|
|
|
696
|
+ * 返回示例:
|
|
|
697
|
+ * {
|
|
|
698
|
+ * "result": {
|
|
|
699
|
+ * "result": {
|
|
|
700
|
+ * "refundId": "RF123456",
|
|
|
701
|
+ * "status": "refundWaitSellerSend"
|
|
|
702
|
+ * },
|
|
|
703
|
+ * "success": true
|
|
|
704
|
+ * }
|
|
|
705
|
+ * }
|
|
|
706
|
+ *
|
|
|
707
|
+ * @param array $params 请求参数
|
|
|
708
|
+ * @return array|false
|
|
|
709
|
+ */
|
|
|
710
|
+ public function createRefund(array $params = [])
|
|
|
711
|
+ {
|
|
|
712
|
+ // --- 参数校验 ---
|
|
|
713
|
+ $requiredFields = ['orderId', 'orderEntryIds', 'disputeReasonId', 'description', 'goodsStatus', 'applyPayment', 'applyCarriage', 'applyReasonId'];
|
|
|
714
|
+ foreach ($requiredFields as $field) {
|
|
|
715
|
+ if (!isset($params[$field])) {
|
|
|
716
|
+ Log::channel('alibaba')->error('[提交售后申请] 缺少必填参数: ' . $field);
|
|
|
717
|
+ return [
|
|
|
718
|
+ 'success' => false,
|
|
|
719
|
+ 'refundId' => '',
|
|
|
720
|
+ 'status' => 'param_missing',
|
|
|
721
|
+ 'rawData' => ['error' => '缺少必填参数: ' . $field],
|
|
|
722
|
+ ];
|
|
|
723
|
+ }
|
|
|
724
|
+ }
|
|
|
725
|
+
|
|
|
726
|
+ $businessParams = [
|
|
|
727
|
+ 'orderId' => (string)$params['orderId'],
|
|
|
728
|
+ 'orderEntryIds' => $params['orderEntryIds'],
|
|
|
729
|
+ 'disputeRequest' => (string)$params['disputeReasonId'],
|
|
|
730
|
+ 'applyPayment' => (string)$params['applyPayment'],
|
|
|
731
|
+ 'applyCarriage' => (string)$params['applyCarriage'],
|
|
|
732
|
+ 'applyReasonId' => (string)$params['applyReasonId'],
|
|
|
733
|
+ 'description' => (string)$params['description'],
|
|
|
734
|
+ 'goodsStatus' => (string)$params['goodsStatus'],
|
|
|
735
|
+ ];
|
|
|
736
|
+
|
|
|
737
|
+ // 可选参数
|
|
|
738
|
+ if (!empty($params['voucher'])) {
|
|
|
739
|
+ $businessParams['voucher'] = $params['voucher'];
|
|
|
740
|
+ }
|
|
|
741
|
+
|
|
|
742
|
+ Log::channel('alibaba')->info('[提交售后申请] 准备请求, params:' . json_encode($businessParams, JSON_UNESCAPED_UNICODE));
|
|
|
743
|
+
|
|
|
744
|
+ // --- 调用API ---
|
|
|
745
|
+ $result = $this->executeParam2(
|
|
|
746
|
+ self::NAMESPACE,
|
|
|
747
|
+ 'alibaba.trade.createRefund',
|
|
|
748
|
+ 1,
|
|
|
749
|
+ $businessParams
|
|
|
750
|
+ );
|
|
|
751
|
+
|
|
|
752
|
+ // 不管API调用是否成功,都返回格式化的结果(包含原始数据)
|
|
|
753
|
+ if ($result === false) {
|
|
|
754
|
+ Log::channel('alibaba')->error('[提交售后申请] API请求失败, params:' . json_encode($businessParams, JSON_UNESCAPED_UNICODE));
|
|
|
755
|
+ return [
|
|
|
756
|
+ 'success' => false,
|
|
|
757
|
+ 'refundId' => '',
|
|
|
758
|
+ 'status' => 'api_failed',
|
|
|
759
|
+ 'rawData' => ['error' => 'API请求失败'],
|
|
|
760
|
+ ];
|
|
|
761
|
+ }
|
|
|
762
|
+
|
|
|
763
|
+ Log::channel('alibaba')->info('[提交售后申请] API请求成功, result:' . json_encode($result, JSON_UNESCAPED_UNICODE));
|
|
|
764
|
+
|
|
|
765
|
+ return $this->formatCreateRefundResult($result);
|
|
|
766
|
+ }
|
|
|
767
|
+
|
|
|
768
|
+ /**
|
|
|
769
|
+ * 格式化提交售后申请返回结果
|
|
|
770
|
+ *
|
|
|
771
|
+ * 成功返回数据结构:
|
|
|
772
|
+ * {
|
|
|
773
|
+ * "result": {
|
|
|
774
|
+ * "result": {
|
|
|
775
|
+ * "refundId": "RF123456",
|
|
|
776
|
+ * "status": "refundWaitSellerSend"
|
|
|
777
|
+ * },
|
|
|
778
|
+ * "success": true
|
|
|
779
|
+ * }
|
|
|
780
|
+ * }
|
|
|
781
|
+ *
|
|
|
782
|
+ * 失败返回数据结构:
|
|
|
783
|
+ * {
|
|
|
784
|
+ * "result": {
|
|
|
785
|
+ * "code": "5000",
|
|
|
786
|
+ * "message": "错误描述",
|
|
|
787
|
+ * "success": false
|
|
|
788
|
+ * }
|
|
|
789
|
+ * }
|
|
|
790
|
+ *
|
|
|
791
|
+ * @param array $result API原始返回数据
|
|
|
792
|
+ * @return array
|
|
|
793
|
+ */
|
|
|
794
|
+ protected function formatCreateRefundResult(array $result): array
|
|
|
795
|
+ {
|
|
|
796
|
+ // 检查 result 层是否存在
|
|
|
797
|
+ $resultData = $result['result'] ?? $result;
|
|
|
798
|
+ $success = $resultData['success'] ?? false;
|
|
|
799
|
+
|
|
|
800
|
+ if ($success) {
|
|
|
801
|
+ // 成功:result.result 中包含 refundId 和 status
|
|
|
802
|
+ $refundResult = $resultData['result'] ?? [];
|
|
|
803
|
+ return [
|
|
|
804
|
+ 'success' => true,
|
|
|
805
|
+ 'refundId' => $refundResult['refundId'] ?? '',
|
|
|
806
|
+ 'status' => $refundResult['status'] ?? '',
|
|
|
807
|
+ 'rawData' => $result,
|
|
|
808
|
+ ];
|
|
|
809
|
+ }
|
|
|
810
|
+
|
|
|
811
|
+ // 失败:result 中包含 code 和 message
|
|
|
812
|
+ return [
|
|
|
813
|
+ 'success' => false,
|
|
|
814
|
+ 'refundId' => '',
|
|
|
815
|
+ 'status' => $resultData['message'] ?? ($resultData['code'] ?? 'api_error'),
|
|
|
816
|
+ 'rawData' => $result,
|
|
|
817
|
+ ];
|
|
|
818
|
+ }
|
|
677
|
819
|
}
|