123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- <?php
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- namespace app\common\server;
-
-
- use app\common\enum\IntegralOrderEnum;
- use app\common\enum\PayEnum;
- use app\common\logic\IntegralOrderRefundLogic;
- use app\common\logic\PaymentLogic;
- use app\common\logic\PayNotifyLogic;
- use app\common\model\Client_;
- use app\common\model\integral\IntegralOrder;
- use app\common\model\Pay;
- use EasyWeChat\Factory;
- use EasyWeChat\Payment\Application;
- use app\common\model\order\OrderLog;
- use app\common\model\order\Order;
- use app\common\model\order\OrderTrade;
- use Endroid\QrCode\QrCode;
- use http\Client;
- use think\facade\Db;
- use think\Exception;
-
-
- class WeChatPayServer
- {
-
- protected static $error = '未知错误';
- protected static $return_code = 0;
-
-
-
- public static function getError()
- {
-
- return self::$error;
- }
-
-
-
- public static function getReturnCode()
- {
-
- return self::$return_code;
- }
-
-
-
-
- public static function unifiedOrder($from, $order, $order_source)
- {
-
- try {
- $wechat_config = self::getWeChatConfig($order, $order_source);
- $auth = $wechat_config['auth'];
- $config = $wechat_config['config'];
- $notify_url = $wechat_config['notify_url'];
-
-
- $check_source = [Client_::mnp, Client_::oa];
- if (!$auth && in_array($order_source, $check_source)) {
- throw new Exception('授权信息失效');
- }
-
- $app = Factory::payment($config);
- $attributes = self::getAttributes($from, $order, $order_source, $auth, $notify_url);
- $result = $app->order->unify($attributes);
- if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
-
-
- if (in_array($order_source, [Client_::mnp, Client_::oa])) {
- $data = $app->jssdk->bridgeConfig($result['prepay_id'], false);
- }
-
-
- if (in_array($order_source, [Client_::ios, Client_::android])) {
- $data = $app->jssdk->appConfig($result['prepay_id'], false);
- }
-
-
- if ($order_source == Client_::pc) {
- $data = self::getNativeCode($result, $order);
- }
-
-
- if ($order_source == Client_::h5) {
- $redirect_url = request()->domain() . '/mobile/pages/user_order/user_order';
- $redirect_url = urlencode($redirect_url);
- $data = $result['mweb_url'] . '&redirect_url=' . $redirect_url;
- }
- return $data;
- } else {
- if (isset($result['return_code']) && $result['return_code'] == 'FAIL') {
- throw new Exception($result['return_msg']);
- }
- if (isset($result['err_code_des'])) {
- throw new Exception($result['err_code_des']);
- }
- throw new Exception('未知原因');
- }
-
- } catch (Exception $e) {
- self::$error = '支付失败:' . $e->getMessage();
- return false;
- }
- }
-
-
-
- public static function getNativeCode($result, $order)
- {
-
- $save_dir = 'uploads/pay_code/';
- $qr_src = md5($order['order_sn'] . mt_rand(10000, 99999)) . '.png';
- $code_url = ROOT_PATH . '/' . $save_dir . $qr_src;
-
- $qrCode = new QrCode();
- $qrCode->setText($result['code_url']);
- $qrCode->setSize(200);
- $qrCode->setWriterByName('png');
- !file_exists($save_dir) && mkdir($save_dir, 777, true);
- $qrCode->writeFile($code_url);
-
-
- if ($fp = fopen($code_url, "rb", 0)) {
- $gambar = fread($fp, filesize($code_url));
- fclose($fp);
- $base64 = chunk_split(base64_encode($gambar));
- $base64 = 'data:image/png;base64,' . $base64;
- }
-
- if (strstr($code_url, $save_dir)) {
- unlink($code_url);
- }
- return $base64;
- }
-
-
-
-
- public static function getAttributes($from, $order, $order_source, $auth, $notify_url)
- {
-
- switch ($from) {
- case 'trade':
- $attributes = [
- 'trade_type' => 'JSAPI',
- 'body' => '商品总订单',
- 'total_fee' => $order['order_amount'] * 100,
- 'notify_url' => $notify_url,
- 'openid' => $auth['openid'] ?? '',
- 'attach' => 'trade'
- ];
- break;
- case 'order':
- $attributes = [
- 'trade_type' => 'JSAPI',
- 'body' => '商品子订单',
- 'total_fee' => $order['order_amount'] * 100,
- 'notify_url' => $notify_url,
- 'openid' => $auth['openid'] ?? '',
- 'attach' => 'order'
- ];
- break;
- case 'recharge':
- $attributes = [
- 'trade_type' => 'JSAPI',
- 'body' => '充值',
- 'total_fee' => $order['order_amount'] * 100,
- 'notify_url' => $notify_url,
- 'openid' => $auth['openid'] ?? '',
- 'attach' => 'recharge'
- ];
- break;
- case 'integral':
- $attributes = [
- 'trade_type' => 'JSAPI',
- 'body' => '积分商城',
- 'total_fee' => $order['order_amount'] * 100,
- 'notify_url' => $notify_url,
- 'openid' => $auth['openid'] ?? '',
- 'attach' => 'integral'
- ];
- break;
- }
-
-
- if ($order_source == Client_::android || $order_source == Client_::ios) {
- $attributes['trade_type'] = 'APP';
- }
-
-
- if ($order_source == Client_::pc) {
- $attributes['trade_type'] = 'NATIVE';
- $attributes['product_id'] = $order['order_sn'];
- $attributes['openid'] = "";
- }
-
-
- if ($order_source == Client_::h5) {
- $attributes['trade_type'] = 'MWEB';
- }
-
-
-
- if ($from == 'trade') {
- $attributes['out_trade_no'] = $order['t_sn'] . $attributes['trade_type'] . $order_source;
- } else {
- $attributes['out_trade_no'] = $order['order_sn'] . $attributes['trade_type'] . $order_source;
- }
- return $attributes;
- }
-
-
-
-
- public static function getWeChatConfig($order, $order_source)
- {
-
- $pay_config = WeChatServer::getPayConfigBySource($order_source);
- $where[] = ['user_id', '=', $order['user_id']];
- $where[] = ['client', '=', $order_source];
- $auth = Db::name('user_auth')->where($where)->find();
-
- $data = [
- 'auth' => $auth,
- 'config' => $pay_config['config'],
- 'notify_url' => $pay_config['notify_url'],
- 'order_source' => $order_source,
- ];
- return $data;
- }
-
-
-
- public static function getOrderLogData($order_id, $user_id, $shop_id)
- {
-
- $order_log_data = [];
- $order_log_data['type'] = 0;
- $order_log_data['channel'] = 101;
- $order_log_data['order_id'] = $order_id;
- $order_log_data['handle_id'] = $user_id;
- $order_log_data['shop_id'] = $shop_id;
- $order_log_data['content'] = 105;
- $order_log_data['create_time'] = time();
-
- return $order_log_data;
-
- }
-
-
-
- public static function notify($config)
- {
-
- $app = new Application($config);
- $response = $app->handlePaidNotify(function ($message, $fail) {
-
- if ($message['return_code'] !== 'SUCCESS') {
- return $fail('通信失败');
- }
-
- if ($message['result_code'] === 'SUCCESS') {
- $extra['transaction_id'] = $message['transaction_id'];
- $attach = $message['attach'];
- $message['out_trade_no'] = mb_substr($message['out_trade_no'], 0, 18);
- switch ($attach) {
- case 'trade':
- $order_trade = OrderTrade::where('t_sn', $message['out_trade_no'])->find();
- $order = Order::where('trade_id', $order_trade['id'])->find();
- if (!$order || $order['pay_status'] >= PayEnum::ISPAID) {
- return true;
- }
- PayNotifyLogic::handle('trade', $message['out_trade_no'], $extra);
- break;
- case 'order':
- $order = Db::name('order')->where(['order_sn' => $message['out_trade_no']])->find();
- if (!$order || $order['pay_status'] >= PayEnum::ISPAID) {
- return true;
- }
- PayNotifyLogic::handle('order', $message['out_trade_no'], $extra);
- break;
- case 'recharge':
- $order = Db::name('recharge_order')->where(['order_sn' => $message['out_trade_no']])->find();
- if (!$order || $order['pay_status'] >= PayEnum::ISPAID) {
- return true;
- }
- PayNotifyLogic::handle('recharge', $message['out_trade_no'], $extra);
- break;
- case 'integral':
-
- $order = IntegralOrder::where(['order_sn' => $message['out_trade_no']])->find();
- if (!$order || $order['refund_status'] == IntegralOrderEnum::IS_REFUND) {
-
- return true;
- }
- if ($order['order_status'] == IntegralOrderEnum::ORDER_STATUS_DOWN) {
-
- IntegralOrderRefundLogic::refundOrderAmount($order['id']);
- return true;
- }
- if ($order['pay_status'] >= PayEnum::ISPAID) {
- return true;
- }
- PayNotifyLogic::handle('integral', $message['out_trade_no'], $extra);
- break;
- }
- } elseif ($message['result_code'] === 'FAIL') {
-
- }
- return true;
- });
- $response->send();
- }
-
-
-
-
- public static function refund($config, $data)
- {
- if (!empty($data["transaction_id"])) {
- $app = Factory::payment($config);
- $result = $app->refund->byTransactionId(
- $data['transaction_id'],
- $data['refund_sn'],
- $data['total_fee'],
- $data['refund_fee']
- );
- return $result;
- } else {
- return false;
- }
- }
-
- }
|