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

654 lines
23 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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');
}
}
?>