www.lightcourse.com/app/home/controller/Payment.php

654 lines
23 KiB
PHP
Raw Normal View History

2022-10-24 02:38:36 +00:00
<?php
/*
* 支付相关处理
*/
namespace app\home\controller;
use think\facade\View;
use think\facade\Lang;
use think\facade\Db;
use Stripe\Stripe;
/**
* ============================================================================
* 联课教育商城系统
* ============================================================================
* 版权所有 2022 刻羽互动科技有限公司,并保留所有权利。
* 网站地址: http://www.o1h.cn
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
* 不允许对程序代码以任何形式任何目的的再发布。
* ============================================================================
* 控制器
*/
class Payment extends BaseMall {
private static $key;
private static $test;
public function initialize() {
parent::initialize(); // TODO: Change the autogenerated stub
Lang::load(base_path() . 'home/lang/'.config('lang.default_lang').'/buy.lang.php');
self::$key = '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';
self::$test = 'sk_test_51KGYh8LqMBqucQSD5wsRQmjy96oRuMu4fx4PwNle6rVovtZU8KKC9CFVHafye62bj6M0CPzFc3iCJUFPWA3Xd8s1005wLqg10M';
}
private function use_predeposit($order_info, $post, $virtual = 0) {
if ($virtual) {
$logic_buy = model('buyvirtual', 'logic');
} else {
$logic_buy = model('buy_1', 'logic');
}
if (empty($post['password'])) {
return $order_info;
}
$member_model = model('member');
$buyer_info = $member_model->getMemberInfoByID(session('member_id'));
if ($buyer_info['member_paypwd'] == '' || $buyer_info['member_paypwd'] != md5($post['password'])) {
return $order_info;
}
if ($buyer_info['available_rc_balance'] == 0) {
$post['rcb_pay'] = null;
}
if ($buyer_info['available_predeposit'] == 0) {
$post['pd_pay'] = null;
}
try {
Db::startTrans();
if (!empty($post['rcb_pay'])) {
$order_info = $logic_buy->rcbPay($order_info, $post, $buyer_info);
}
if (!empty($post['pd_pay'])) {
$order_info = $logic_buy->pdPay($order_info, $post, $buyer_info);
}
Db::commit();
} catch (\Exception $e) {
Db::rollback();
exit($e->getMessage());
}
return $order_info;
}
private function get_order_info($result) {
//计算本次需要在线支付的订单总金额
$pay_amount = 0;
$pay_order_id_list = array();
if (!empty($result['data']['order_list'])) {
foreach ($result['data']['order_list'] as $order_info) {
if ($order_info['order_state'] == ORDER_STATE_NEW) {
$pay_amount += $order_info['order_amount'] - $order_info['pd_amount'] - $order_info['rcb_amount'];
$pay_order_id_list[] = $order_info['order_id'];
}
}
}
if (round($pay_amount,2) == 0) {
$result['data']['pay_end'] = 1;
} else {
$result['data']['pay_end'] = 0;
}
$result['data']['api_pay_amount'] = ds_price_format($pay_amount);
//临时注释
if (!empty($pay_order_id_list)) {
$update = model('order')->editOrder(array('payment_time'=>TIMESTAMP), array(array('order_id', 'in', $pay_order_id_list)));
// if (!$update) {
// exit('更新订单信息发生错误,请重新支付');//因为微信支付时会重定向获取openid所以会更新两次
// }
}
//如果是开始支付尾款,则把支付单表重置了未支付状态,因为支付接口通知时需要判断这个状态
if (isset($result['data']['if_buyer_repay'])) {
$update = model('order')->editOrderpay(array('api_paystate' => 0), array('pay_id' => $result['data']['pay_id']));
if (!$update) {
exit(lang('order_pay_fail'));
}
$result['data']['api_paystate'] = 0;
}
return $result;
}
private function get_vr_order_info($result) {
//计算本次需要在线支付的订单总金额
$pay_amount = 0;
if ($result['data']['order_state'] == ORDER_STATE_NEW) {
$pay_amount += $result['data']['order_amount'] - $result['data']['pd_amount'] - $result['data']['rcb_amount'];
}
if ($pay_amount == 0) {
$result['data']['pay_end'] = 1;
} else {
$result['data']['pay_end'] = 0;
}
$result['data']['api_pay_amount'] = ds_price_format($pay_amount);
//临时注释
//$update = model('order')->editOrder(array('api_pay_time'=>TIMESTAMP),array('order_id'=>$result['data']['order_id']));
//if(!$update) {
// return array('error' => '更新订单信息发生错误,请重新支付');
//}
//计算本次需要在线支付的订单总金额
$pay_amount = $result['data']['order_amount'] - $result['data']['pd_amount'] - $result['data']['rcb_amount'];
$result['data']['api_pay_amount'] = ds_price_format($pay_amount);
return $result;
}
/**
* 实物商品订单
*/
public function real_order() {
$pay_sn = input('post.pay_sn');
$payment_code = input('post.payment_code');
$url = url('Memberorder/index');
if (!preg_match('/^\d{20}$/', $pay_sn)) {
$this->error(lang('param_error'), $url);
}
$logic_payment = model('payment', 'logic');
$result = $logic_payment->getPaymentInfo($payment_code);
if (!$result['code']) {
$this->error($result['msg'], $url);
}
$payment_info = $result['data'];
//计算所需支付金额等支付单信息
$result = $logic_payment->getRealOrderInfo($pay_sn, session('member_id'));
if (!$result['code']) {
$this->error($result['msg'], $url);
}
if ($result['data']['api_paystate'] || empty($result['data']['api_pay_amount'])) {
$this->error(lang('no_payment_required_this_order'), $url);
}
$result['data']['order_list'] = $this->use_predeposit($result['data']['order_list'], input('param.'), 0);
$result = $this->get_order_info($result);
if ($result['data']['pay_end'] == 1) {
//站内支付了全款
$this->redirect($url);return;
}
//转到第三方API支付
$this->_api_pay($result['data'], $payment_info);
}
/**
* 虚拟商品购买
*/
public function vr_order() {
$order_sn = input('post.order_sn');
$payment_code = input('post.payment_code');
$url = url('Membervrorder/index');
if (!preg_match('/^\d{20}$/', $order_sn)) {
$this->error(lang('param_error'));
}
$logic_payment = model('payment', 'logic');
$result = $logic_payment->getPaymentInfo($payment_code);
if (!$result['code']) {
$this->error($result['msg'], $url);
}
$payment_info = $result['data'];
//计算所需支付金额等支付单信息
$result = $logic_payment->getVrOrderInfo($order_sn, session('member_id'));
if (!$result['code']) {
$this->error($result['msg'], $url);
}
if ($result['data']['order_state'] != ORDER_STATE_NEW || empty($result['data']['api_pay_amount'])) {
$this->error(lang('no_payment_required_this_order'), $url);
}
$result['data'] = $this->use_predeposit($result['data'], input('param.'), 1);
$result = $this->get_vr_order_info($result);
if ($result['data']['pay_end'] == 1) {
$this->redirect($url);return;
}
//转到第三方API支付
$this->_api_pay($result['data'], $payment_info);
}
/**
* 预存款充值
*/
public function pd_order() {
$pdr_sn = input('param.pdr_sn');
$payment_code = input('param.payment_code');
$url = url('Predeposit/index');
if (!preg_match('/^\d{20}$/', $pdr_sn)) {
$this->error(lang('param_error'), $url);
}
$logic_payment = model('payment', 'logic');
$result = $logic_payment->getPaymentInfo($payment_code);
if (!$result['code']) {
$this->error($result['msg'], $url);
}
$payment_info = $result['data'];
$result = $logic_payment->getPdOrderInfo($pdr_sn, session('member_id'));
if (!$result['code']) {
$this->error($result['msg'], $url);
}
if ($result['data']['pdr_payment_state'] || empty($result['data']['api_pay_amount'])) {
$this->error(lang('no_payment_required'), $url);
}
//转到第三方API支付
$this->_api_pay($result['data'], $payment_info);
}
/**
* 第三方在线支付接口
*
*/
private function _api_pay($order_info, $payment_info) {
try{
$payment_api = new $payment_info['payment_code']($payment_info);
}catch(\Exception $e){
$this->error($e->getMessage());
}
if (in_array($payment_info['payment_code'],array('wxpay_native','allinpay'))) {
if (!extension_loaded('curl')) {
$this->error(lang('please_check_system_configuration'));
}
if (array_key_exists('order_list', $order_info)) {
View::assign('order_list', $order_info['order_list']);
View::assign('args', 'buyer_id=' . session('member_id') . '&pay_id=' . $order_info['pay_id']);
} else {
View::assign('order_list', array());
if ($order_info['order_type'] == 'pd_order') {
View::assign('args', 'buyer_id=' . session('member_id') . '&pdr_sn=' . $order_info['pdr_sn']);
} else {
View::assign('args', 'buyer_id=' . session('member_id') . '&order_id=' . (isset($order_info['order_id']) ? $order_info['order_id'] : ''));
}
}
View::assign('api_pay_amount', $order_info['api_pay_amount']);
try{
$pay_url=base64_encode(ds_encrypt($payment_api->get_payform($order_info), MD5_KEY));
}catch(\Exception $e){
$this->error($e->getMessage());
}
View::assign('pay_url', $pay_url);
View::assign('nav_list', rkcache('nav', true));
if($payment_info['payment_code']=='wxpay_native'){
$pay_method=lang('pay_method_wechat');
}elseif($payment_info['payment_code']=='allinpay'){
$paytype=input('param.paytype');
switch($paytype){
case 'W01':
$pay_method=lang('pay_method_wechat');
break;
case 'A01':
$pay_method=lang('pay_method_alipay');
break;
case 'Q01':
$pay_method=lang('pay_method_tenpay');
break;
case 'U01':
$pay_method=lang('pay_method_unionpay');
break;
default:
$this->error(lang('please_check_system_configuration'));
}
}
View::assign('pay_method',$pay_method);
echo View::fetch($this->template_dir . 'wxpay');
} else {
try{
$pay_url=$payment_api->get_payform($order_info);
}catch(\Exception $e){
$this->error($e->getMessage());
}
@header("Location: " . $pay_url);
}
exit();
}
/**
* 二维码显示(微信扫码支付)
*/
public function qrcode() {
$data = base64_decode(input('data'));
$data = ds_decrypt($data, MD5_KEY, 30);
include_once root_path(). 'extend/qrcode/phpqrcode.php';
\QRcode::png($data);
}
/**
* 扫码支付结果判断
*/
public function query_state() {
if (intval(input('param.pay_id')) > 0) {
$info = model('order')->getOrderpayInfo(array(
'pay_id' => intval(input('param.pay_id')),
'buyer_id' => intval(input('param.buyer_id'))
));
exit(json_encode(array(
'state' => ($info['api_paystate'] == '1'), 'pay_sn' => $info['pay_sn'], 'type' => 'real_order'
)));
} elseif (intval(input('param.order_id')) > 0) {
$info = model('vrorder')->getVrorderInfo(array(
'order_id' => intval(input('param.order_id')),
'buyer_id' => intval(input('param.buyer_id'))
));
exit(json_encode(array(
'state' => ($info['order_state'] == '20'), 'pay_sn' => $info['order_sn'], 'type' => 'vr_order'
)));
} else {
$result = model('payment', 'logic')->getPdOrderInfo(input('param.pdr_sn'), input('param.buyer_id'));
exit(json_encode(array('state' => $result['code'] && $result['data']['pdr_payment_state'], 'pdr_sn' => $result['code']?$result['data']['pay_sn']:'', 'type' => 'pd_order')));
}
}
/**
*
* @param type $payment_code 共用回调方法
* @param type $show_code 实际支付方式名称
*/
public function notify($payment_code,$show_code='') {
$logic_payment = model('payment', 'logic');
$result = $logic_payment->getPaymentInfo($payment_code);
$payment_info = $result['data'];
if($show_code){
$result = $logic_payment->getPaymentInfo($show_code);
$payment_info['payment_config'] = array_merge($payment_info['payment_config'],$result['data']['payment_config']);
}
//创建支付接口对象
$payment_api = new $payment_code($payment_info);
//对进入的参数进行远程数据判断
$verify = $payment_api->verify_notify();
if ($verify['trade_status'] != 1) {
exit;
}
$out_trade_no = $verify['out_trade_no']; #内部订单号
$trade_no = $verify['trade_no']; #交易订单号
$order_type = $verify['order_type']; #交易类型
$update_result = $logic_payment->updateOrder($out_trade_no, $trade_no, $order_type, $show_code?$show_code:$payment_code);
exit($update_result ? 'success' : 'fail');
}
/**
* 支付接口同步返回路径
*/
public function alipay_return() {
$result = explode('-', input('param.out_trade_no'));
$out_trade_no = $result['1']; //返回的支付单号
$order_type = $result['0'];
$order_amount = input('param.total_amount'); //订单金额
$trade_no = input('param.trade_no');
$payment_code = 'alipay';
$logic_payment = model('payment', 'logic');
//取得支付方式
$result = $logic_payment->getPaymentInfo($payment_code);
if (!$result['code']) {
$this->error($result['msg'], 'Memberorder/index');
}
$payment_info = $result['data'];
//创建支付接口对象
$payment_api = new $payment_info['payment_code']($payment_info);
//返回参数判断
$verify = $payment_api->return_verify();
if (!$verify) {
$this->error(lang('payment_data_validation_failed'), 'Memberorder/index');
}
//支付成功后跳转
if ($order_type == 'real_order') {
$pay_ok_url = '/buy/pay_ok?pay_sn=' . $out_trade_no . '&pay_amount=' . ds_price_format($order_amount);
} elseif ($order_type == 'vr_order') {
$pay_ok_url = '/buyvirtual/pay_ok?order_sn=' . $out_trade_no . '&order_amount=' . ds_price_format($order_amount);
} elseif ($order_type == 'pd_order') {
$pay_ok_url = '/predeposit/index';
}
header("Location:$pay_ok_url");
exit;
}
//测试stripe支付
public function pay()
{
return View::fetch($this->template_dir.'pay');
}
//stripe支付异步通知
public function stripe_notify()
{
$payload = @file_get_contents('php://input');
file_put_contents('1.txt', $payload, FILE_APPEND);
require_once root_path() . 'vendor/autoload.php';
require_once root_path() . 'vendor/stripe/stripe-php/init.php';
\Stripe\Stripe::setApiKey(self::$key);
// $payload = file_get_contents('https://light.haix.cn/1.txt');
$event = null;
try {
$event = \Stripe\Event::constructFrom(
json_decode($payload, true)
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
// http_response_code(400);
exit();
}
$payment_intent = '';
// Handle the event
switch ($event->type) {
case 'charge.succeeded':
$succeeded = $event->data->object;
$content = json_encode($succeeded);
if ($succeeded->status == 'succeeded'){
$payment_intent = $succeeded->payment_intent;
}
break;
default:
echo 'Received unknown event type ' . $event->type;
break;
}
if (empty($payment_intent)) {
return false;
}
$order_model = model('order');
$logic_payment = model('payment', 'logic');
$o = $order_model->getOrderBy($payment_intent);
$order = $logic_payment->getRealOrderInfo($o['pay_sn']);
$order_list = $order['data']['order_list'];
$result = $logic_payment->updateRealOrder($o['pay_sn'], 'stripe', $order_list, $payment_intent);
}
//stripe支付
public function stripe()
{
$pay_sn = input('post.pay_sn');
$payment_code = input('post.payment_code');
$url = '/Memberorder/index.html';
if (!preg_match('/^\d{20}$/', $pay_sn)) {
$this->error(lang('param_error'), $url);
}
$logic_payment = model('payment', 'logic');
$result = $logic_payment->getPaymentInfo($payment_code);
$payment_info = $result['data'];
//计算所需支付金额等支付单信息
$result = $logic_payment->getRealOrderInfo($pay_sn, session('member_id'));
if (!$result['code']) {
$this->error($result['msg'], $url);
}
if ($result['data']['api_paystate'] || empty($result['data']['api_pay_amount'])) {
$this->error(lang('no_payment_required_this_order'), $url);
}
$result['data']['order_list'] = $this->use_predeposit($result['data']['order_list'], input('param.'), 0);
$result = $this->get_order_info($result);
if ($result['data']['pay_end'] == 1) {
//站内支付了全款
$this->redirect($url);return;
}
$order_model = model('order');
$detail = $order_model->getOrdergoodsInfo(['order_id' => $result['data']['order_list'][0]['order_id']]);
//新的
$product = [
'name' => 'Order Number' . $pay_sn ,
'images' => [
'http://test.lightcourse.com/static/home/new/images/logo.png',
]
];
$amount = intval($result['data']['api_pay_amount']) * 100;
$result = self::stripePay($product, $amount, $result['data']['order_list'][0]['order_id']);
}
/**
* Stripe支付
* @access private
* @author super
* @date 2020-11-04
* @param array $product 商品信息
* @param int|float $amount 支付金额
* @param array $pay_type 支付类型
* @param string $currency 货币类型 小写
* @return array
*/
private static function stripePay($product, $amount, $order_id, $pay_type = ['card'], $currency = 'usd')
{
require_once root_path() . 'vendor/autoload.php';
require_once root_path() . 'vendor/stripe/stripe-php/init.php';
\Stripe\Stripe::setApiKey(self::$key);
header('Content-Type: application/json');
$YOUR_DOMAIN = 'http://test.lightcourse.com/';
$checkout_session = \Stripe\Checkout\Session::create([
'payment_method_types' => $pay_type,
'line_items' => [[
'price_data' => [
'currency' => $currency,
'unit_amount' => $amount,
'product_data' => $product
],
'quantity' => 1,
]],
'mode' => 'payment',
'success_url' => $YOUR_DOMAIN . '/buy/succ?order_id='.$order_id, // 支付成功后跳转url
'cancel_url' => $YOUR_DOMAIN . '/Memberorder/index.html', // 支付失败后跳转url
]);
// var_dump($checkout_session->url);die;
$jump = $checkout_session->url;
//return ['id' => $checkout_session->id, 'payment_intent' => $checkout_session->payment_intent];
// payment_intent是识别支付与通知关系的唯一凭证
$order_model = model('order');
$intent = $checkout_session->payment_intent;
$order_model->editOrder(array('trade_no'=>$intent), array(
'order_id' => $order_id));
header("location:$jump");exit();
}
/**
* 通联异步通知
*/
public function allinpay_notify(){
$this->notify('allinpay');
}
/**
* 微信扫码支付异步通知
*/
public function wxpay_native_notify() {
$this->notify('wxpay_native');
}
/**
* 小程序支付异步通知
*/
public function wxpay_minipro_notify() {
$this->notify('wxpay_native','wxpay_minipro');
}
/**
* 微信支付支付异步通知
*/
public function wxpay_jsapi_notify() {
$this->notify('wxpay_native','wxpay_jsapi');
}
/**
* 微信H5支付异步通知
*/
public function wxpay_h5_notify() {
$this->notify('wxpay_native','wxpay_h5');
}
/**
* 微信APP支付异步通知
*/
public function wxpay_app_notify() {
$this->notify('wxpay_native','wxpay_app');
}
/**
* 通知处理(支付宝异步对账)
*/
public function alipay_notify() {
$this->notify('alipay');
}
/**
* 支付宝APP支付异步通知
*/
public function alipay_app_notify() {
$this->notify('alipay_app');
}
/**
* 支付宝wap支付异步通知
*/
public function alipay_h5_notify() {
$this->notify('alipay','alipay_h5');
}
}
?>