AlipayThirdOrderForm.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\client\models\v1;
  8. use AopClient;
  9. use app\models\Goods;
  10. use app\models\Option;
  11. use app\models\Order;
  12. use app\models\OrderDetail;
  13. use app\models\StoreAliMini;
  14. use app\models\User;
  15. use app\utils\Alipay\alipaySdk\aop\request\AlipayMerchantItemFileUploadRequest;
  16. use app\utils\Alipay\alipaySdk\aop\request\AlipayMerchantOrderSyncRequest;
  17. use app\utils\CurlHelper;
  18. use yii\base\Model;
  19. include_once \Yii::$app->basePath . "/utils/Alipay/alipaySdk/aop/AopClient.php";
  20. class AlipayThirdOrderForm extends Model
  21. {
  22. public $goods_id;
  23. public $order_id;
  24. public $mini_id;
  25. public $base_info;
  26. public function rules()
  27. {
  28. return [
  29. [['goods_id', 'order_id'], 'integer']
  30. ];
  31. }
  32. public function __construct($config = [])
  33. {
  34. parent::__construct($config);
  35. //三方平台Appid
  36. $this->base_info['appid'] = Option::get("alipay_appid", 0, 'saas')['value'];
  37. //获取当前时间戳
  38. $this->base_info['timestamp'] = date("Y-m-d H:i:s");
  39. //设置加解密方式
  40. $this->base_info['sign_type'] = "RSA2";
  41. //获取私钥
  42. $this->base_info['private_key'] = Option::get("alipay_app_private_key", 0, 'saas')['value'];
  43. //获取公钥
  44. $this->base_info['public_key'] = Option::get("alipay_public_key", 0, 'saas')['value'];
  45. //获取ase_key,加签方式
  46. $this->base_info['alipay_aes_key'] = Option::get("alipay_aes_key", 0, 'saas')['value'];
  47. }
  48. public function miniCommon($request, $biz_content = null, $is_hidden_token = 0, $token = '')
  49. {
  50. try {
  51. //请求的基础信息
  52. $base_info = $this->base_info;
  53. //小程序ID
  54. $mini_id = $this->mini_id ?: get_mini_id();
  55. if (!empty($mini_id)) {
  56. $store_mini = StoreAliMini::findOne($mini_id);
  57. //如果小程序ID存在,则将token从模板转成商家小程序的token
  58. if (!empty($store_mini->auth_token)) {
  59. $auth_token = $store_mini->auth_token;
  60. }
  61. } else {
  62. throw new \Exception("获取不到token");
  63. }
  64. //设置基础请求数据
  65. $aop = new AopClient();
  66. //设置appid
  67. $aop->appId = $base_info['appid'];
  68. //设置私钥
  69. $aop->rsaPrivateKey = $base_info['private_key'];
  70. //设置公钥
  71. $aop->alipayrsaPublicKey = $base_info['public_key'];
  72. //设置ase_key,加签方式
  73. $aop->encryptKey = $base_info['alipay_aes_key'];
  74. //设置加解密方式
  75. $aop->signType = $base_info['sign_type'];
  76. //处理没有biz_content情况
  77. if ($biz_content) {
  78. $request->setBizContent($biz_content);
  79. }
  80. //处理不需要token情况
  81. if ($is_hidden_token === 0) {
  82. //开始请求
  83. $result = $aop->execute($request, null, $auth_token);
  84. } else {
  85. //开始请求
  86. $result = $aop->execute($request);
  87. }
  88. //请求后的数据处理
  89. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  90. return $result->$responseNode;
  91. } catch (\Exception $e) {
  92. return [
  93. 'sub_msg' => $e->getMessage()
  94. ];
  95. }
  96. }
  97. //保存商品素材
  98. public function updateGoodsFile($goods_id)
  99. {
  100. try {
  101. if (empty($goods_id)) {
  102. $goods_id = $this->goods_id;
  103. }
  104. $goods = Goods::findOne($goods_id);
  105. if (!empty($goods->cover_pic)) {
  106. $url_path = $this->saveTempImage($goods->cover_pic);
  107. $request = new AlipayMerchantItemFileUploadRequest();
  108. $request->setScene("SYNC_ORDER");
  109. $request->setFileContent('@' . $url_path);
  110. $form = new \app\modules\admin\models\AlipayThirdForm();
  111. $form->store_id = $goods->store_id;
  112. $result = $form->miniCommon($request, 1);
  113. // $result = $this->miniCommon($request);
  114. if (!empty($result->code) && $result->code == 10000) {
  115. $goods->material_id = $result->material_id;
  116. $goods->material_key = $result->material_key;
  117. if (!$goods->save()) {
  118. throw new \Exception($goods->errors);
  119. }
  120. return [
  121. 'code' => 0,
  122. 'msg' => "添加商品素材成功",
  123. 'data' => $result
  124. ];
  125. }
  126. throw new \Exception($result->sub_msg);
  127. }
  128. throw new \Exception("文件信息不存在");
  129. } catch (\Exception $e) {
  130. return [
  131. 'code' => 1,
  132. 'msg' => $e->getMessage()
  133. ];
  134. }
  135. }
  136. //保存订单信息
  137. public function updateOrderInfo($order_id, $model = null)
  138. {
  139. try {
  140. if (empty($order_id)) {
  141. throw new \Exception("获取订单信息失败");
  142. }
  143. //假设多种订单类型
  144. if (empty($model)) {
  145. $model = Order::find();
  146. }
  147. $order = $model->where(['id' => $order_id])->asArray()->one();
  148. if (empty($order)) {
  149. throw new \Exception("订单信息不存在");
  150. }
  151. $store_id = $order['store_id'];
  152. $form = new \app\modules\admin\models\AlipayThirdForm(['store_id' => $store_id]);
  153. //更换订单状态
  154. $status = $order['trade_status'];
  155. switch ($status) {//0:待发货,1:已取消,2:已发货,3:已确认
  156. case 0:
  157. $status = "TO_SEND_GOODS";
  158. break;
  159. case 1:
  160. $status = "REFUNDING";
  161. break;
  162. case 2:
  163. $status = "IN_DELIVERY";
  164. $form->AlipayOpenMiniOrderDeliverySend($order);
  165. break;
  166. case 3:
  167. $status = "CLOSED";
  168. $form->AlipayOpenMiniOrderDeliveryReceive($order);
  169. break;
  170. }
  171. $refund = \app\models\OrderRefund::find()->where(['order_id' => $order['id'], 'is_delete' => 0, 'status' => 1, 'store_id' => $order['store_id']])->orderBy('id DESC')->one();
  172. if($refund){
  173. $status = "REFUNDED";
  174. }
  175. $order_detail = OrderDetail::find()->alias('od')->where(['od.order_id' => $order['id']])
  176. ->leftJoin(['g' => Goods::tableName()], 'od.goods_id = g.id')
  177. ->select('od.id, od.order_id, od.num, od.goods_name, g.material_id, g.price, od.goods_id')->asArray()->all();
  178. $goods_data = [];
  179. if(is_open_platform()){
  180. $mini = StoreAliMini::findOne(['store_id' => $store_id, 'is_cancel' => 0, 'is_use' => 1]);
  181. $app_id = $mini->auth_app_id;
  182. $this->mini_id = $mini->id;
  183. }else{
  184. $value = Option::get(Option::OPTOPN_KEY, $store_id, 'alipay')['value'];
  185. $conf = json_decode($value, true);
  186. $app_id = $conf['app_id'];
  187. }
  188. $user = User::findOne($order['user_id']);
  189. foreach ($order_detail as $index => $item) {
  190. //获取素材id
  191. $material_id = $item['material_id'];
  192. if (empty($item['material_id'])) {
  193. $result = $this->updateGoodsFile($item['goods_id']);
  194. if ($result['code'] === 0) {
  195. $material_id = $result['data']->material_id;
  196. }
  197. }
  198. $goods_data[$index]['item_name'] = $item['goods_name'];
  199. $goods_data[$index]['quantity'] = $item['num'];
  200. $goods_data[$index]['unit_price'] = $item['price'];
  201. $goods_data[$index]['ext_info'] = [
  202. 'ext_key' => 'image_material_id',
  203. 'ext_value' => $material_id
  204. ];
  205. }
  206. $data = json_encode([
  207. 'amount' => $order['pay_price'],
  208. 'order_modified_time' => date("Y-m-d H:i:s") . '.000',
  209. 'order_create_time' => date("Y-m-d H:i:s", $order['created_at']),
  210. 'pay_amount' => $order['pay_price'],
  211. 'item_order_list' => $goods_data,
  212. 'trade_no' => $order['alipay_trade_no'],
  213. 'buyer_id' => $user->alipay_open_id,
  214. 'out_biz_no' => $order['order_no'],
  215. 'ext_info' => [
  216. [
  217. 'ext_key' => 'merchant_order_status',
  218. 'ext_value' => $status
  219. ],
  220. [
  221. 'ext_key' => 'merchant_biz_type',
  222. 'ext_value' => "KX_SHOPPING"
  223. ],
  224. [
  225. 'ext_key' => 'merchant_order_link_page',
  226. 'ext_value' => "/order/order-detail/order-detail?id=" . $order_id
  227. ],
  228. [
  229. 'ext_key' => 'tiny_app_id',
  230. 'ext_value' => $app_id
  231. ]
  232. ]
  233. ]);
  234. $query = new AlipayMerchantOrderSyncRequest();
  235. $form->store_id = $store_id;
  236. $form->biz_content = $data;
  237. $result = $form->miniCommon($query);
  238. // $result = $this->miniCommon($query, $data);
  239. $file_name = \Yii::$app->runtimePath . '/logs/app_alipay.log';
  240. file_put_contents($file_name, "\r\n" . '[订单信息回传][' . date('Y-m-d H:i:s') . ']' . json_encode($result), FILE_APPEND);
  241. if (!empty($result->code) && $result->code == 10000) {
  242. return [
  243. 'code' => 0,
  244. 'msg' => "success",
  245. 'data' => $result
  246. ];
  247. }
  248. throw new \Exception(json_encode($result));
  249. } catch (\Exception $e) {
  250. \Yii::error($e);
  251. return [
  252. 'code' => 1,
  253. 'msg' => $e->getMessage()
  254. ];
  255. }
  256. }
  257. //获取网络图片到临时目录
  258. public function saveTempImage($url)
  259. {
  260. if (strpos($url, 'http') === false) {
  261. $url = 'http:' . trim($url);
  262. }
  263. if (!is_dir(\Yii::$app->runtimePath . '/image')) {
  264. mkdir(\Yii::$app->runtimePath . '/image');
  265. }
  266. $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg';
  267. CurlHelper::download($url, $save_path);
  268. return $save_path;
  269. }
  270. }