= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp); // $verifiedStatus = Rsa::verify( // Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), // $inWechatpaySignature, // $platformPublicKeyInstance // ); // if ($timeOffsetStatus && $verifiedStatus) { if ($timeOffsetStatus) { $inBodyArray = (array)json_decode($inBody, true); ['resource' => [ 'ciphertext' => $ciphertext, 'nonce' => $nonce, 'associated_data' => $aad ]] = $inBodyArray; $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad); return (array)json_decode($inBodyResource, true); } else { return false; } } public function builder($config) { self::$mp_config = $config; $merchantPrivateKeyFilePath = 'file://' . self::$mp_config['pem_path']; $platformCertificateFilePath = 'file://' . self::$mp_config['cer_path']; $merchantId = self::$mp_config['mchid']; $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE); self::$mp_config['pem_key'] = $merchantPrivateKeyInstance; $merchantCertificateSerial = self::$mp_config['cer_num']; $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC); $platformCertificateSerial = self::$mp_config['v3']; self::$mp_instance = Builder::factory([ 'mchid' => $merchantId, 'serial' => $merchantCertificateSerial, 'privateKey' => $merchantPrivateKeyInstance, 'certs' => [ $platformCertificateSerial => $platformPublicKeyInstance, ], ]); } public function refund($config) { $res = false; try { $resp = self::$mp_instance ->v3->refund->domestic->refunds ->post([ 'json' => [ 'transaction_id' => $config['transaction_id'], 'out_refund_no' => $config['out_refund_no'], 'amount' => [ 'refund' => $config['total'], 'total' => $config['total'], 'currency' => 'CNY', ], ], ]); $res = json_decode($resp->getBody(), true); } catch (\Exception $e) { if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); $res = json_decode($r->getBody(), true); } } return $res; } public function create($config) { $res = false; try { $post_data = [ 'appid' => self::$mp_config['appid'], 'mchid' => self::$mp_config['mchid'], 'description' => $config['description'], 'out_trade_no' => $config['out_trade_no'], 'notify_url' => $config['notify_url'], 'amount' => [ 'total' => $config['total'], ], 'payer' => [ 'openid' => $config['openid'] ], 'settle_info' => [ 'profit_sharing' => $config['profit_sharing'], ] ]; $resp = self::$mp_instance ->v3->pay->transactions->jsapi ->post([ 'json' => $post_data, ]); $res = json_decode($resp->getBody(), true); } catch (\Exception $e) { if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); $res = json_decode($r->getBody(), true); } } $params = [ 'appId' => self::$mp_config['appid'], 'timeStamp' => (string)time(), 'nonceStr' => self::nonce(), 'package' => 'prepay_id=' . $res['prepay_id'], ]; $params += ['paySign' => Rsa::sign( Formatter::joinedByLineFeed(...array_values($params)), self::$mp_config['pem_key'] ), 'signType' => 'RSA']; $wc_chat_pay = new WeChatPay(); $wc_chat_pay->out_trade_no = $config['out_trade_no']; $wc_chat_pay->post_data = json_encode($post_data, JSON_UNESCAPED_UNICODE); $wc_chat_pay->params = json_encode($params, JSON_UNESCAPED_UNICODE); $wc_chat_pay->save(); return [ 'appid' => $params['appId'], 'timestamp' => $params['timeStamp'], 'nonce_str' => $params['nonceStr'], 'package' => $params['package'], 'pay_sign' => $params['paySign'], 'sign_type' => $params['signType'], ]; } public function profitsharing($sharing_data) { $res = false; try { $post_data = [ 'appid' => self::$mp_config['appid'], 'transaction_id' => $sharing_data['transaction_id'], 'out_order_no' => 'P' . $sharing_data['transaction_id'], 'receivers' => $sharing_data['receivers'], 'unfreeze_unsplit' => true ]; $resp = self::$mp_instance ->v3->profitsharing->orders ->post([ 'json' => $post_data, ]); $res = json_decode($resp->getBody(), true); } catch (\Exception $e) { if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); $res = json_decode($r->getBody(), true); } } return $res; } public function profitsharing_return($return_data) { $res = false; try { $resp = self::$mp_instance ->v3->profitsharing->returnOrders ->post([ 'json' => $return_data, ]); $res = json_decode($resp->getBody(), true); } catch (\Exception $e) { if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); $res = json_decode($r->getBody(), true); } } return $res; } public function check($out_trade_no) { $res = false; try { $resp = self::$mp_instance ->v3->pay->transactions->outTradeNo->_out_trade_no_ ->get([ 'query' => ['mchid' => self::$mp_config['mchid']], 'out_trade_no' => (string)$out_trade_no, ]); $res = json_decode($resp->getBody(), true); } catch (\Exception $e) { if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) { $r = $e->getResponse(); $res = json_decode($r->getBody(), true); } } return $res; } public static function nonce($l = 16) { $charts = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789"; $max = strlen($charts) - 1; $noncestr = ""; for ($i = 0; $i < $l; $i++) { $noncestr .= $charts[rand(0, $max)]; } return $noncestr; } }