1、后端逻辑代码:
(1)控制器层:
/**
* Created by PhpStorm.
* User: lph
* Date: 2018/7/5
* Time: 19:16
*/
namespace App\Http\Controllers;
use App\Business\Exceptions\BusinessException;
use App\Business\PaymentBusiness;
use App\Business\Payment\Flow\BaseFlow;
use App\Models\PrimaryOrder;
use App\Models\UserPaymentOrder;
use App\Models\UserUpgradeOrder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\JsonResponse;
use Validator, Log, DB;
use App\Services\StripePay;
class StripePayController extends Controller
{
/**
* 信用卡支付 2018-07-06
* @author oliver xu
* @param Request $request
* @return Json
*/
public function paid(Request $request){
// 验证参数
$v = Validator::make($request->all(), [
'amount' => 'required|string',
'currency' => 'required|in:sgd',
'source' => 'required',
'receipt_email' => 'email',
'order_sn' => 'required|string',
],[
'amount.required' => '支付金额必填',
'amount.string' => '支付金额必须为字符串',
'currency.required' => '货币类型必填默认sgd',
'currency.in' => '货币只有一种sgd',
'source.required' => '支付来源必填', //未保存客户银行卡信息的 只能调用stripe.js 获取token
'receipt_email.email' => '接收邮件格式有误',
'order_sn.required' => '订单ID必填',
'order_sn.string' => '订单ID必须为字符串',
]);
if($v->fails())
{
return $this->format('1', $v->errors()->all()[0], null,'fail');
}
$businessName = 'OrderInfo';
$payProvider = $request->get('payProvider');
$orderId = PrimaryOrder::where('order_sn',$request->order_sn)->value("order_id");
if (!$orderId){
return $this->format('1', $request->order_sn."支付订单不存在", null,'fail');
}
Log::info('获取订单ID:'.$orderId);
$business = BaseFlow::createBusinessFlow($businessName);
$paymentOrder = new UserPaymentOrder();
$order =null;
$isOrder = $paymentOrder->where('order_id',$orderId)->first();
if (!$isOrder){
\DB::transaction(function()use($orderId,$business,$paymentOrder,$businessName,$payProvider,&$order){
$order = $business->createOrderById($orderId,$payProvider);
$paymentOrder->pay_provider =$payProvider;
$paymentOrder->pay_type = 1;
$paymentOrder->business = $businessName;
$paymentOrder->user_id = Auth::user()->user_id;
$paymentOrder->order_id =$order->order_id;
$paymentOrder->price = $order->price;
$paymentOrder->subject =$order->subject;
$paymentOrder->desc =$order->desc;
$paymentOrder->goods_list = json_encode($order->goods_list);
$paymentOrder->trade_no = $order->trade_no;
$paymentOrder->state = 1;
$paymentOrder->save();
});
}elseif (in_array($isOrder->state,[2,3])){
return $this->format('1', '已经支付', null,'success');
}
$paymentOrderInfo = $paymentOrder->where('order_id',$orderId)->first();
try {
StripePay::init();
$param = [
'amount' => _isLocal() ? 50 : $paymentOrderInfo->price*100,
'currency' => $request->currency,
'source' => $request->source,
'metadata' => [
'order_sn'=> $paymentOrderInfo->trade_no,
'amount'=> _isLocal() ? 50 : $paymentOrderInfo->price,
'business'=> $paymentOrderInfo->business,
'ordered_at' =>$paymentOrderInfo->created_at,
],
// 'customer' => $paymentOrderInfo->trade_no,
];
Log::info("start step-3");
// if ($request->has('user_id')) {
// $param['customer'] = $request->user_id;
// }
if ($request->has('receipt_email')) {
$param['receipt_email'] = $request->receipt_email;
}
//支付对象
$chargeObj = null;
Log::info("charge对象内容前:".json_encode($param));
$charge = \Stripe\Charge::create($param);
Log::info("charge对象内容:".json_encode($charge));
$charge = json_encode($charge);
if ($charge) {
$chargeObj = json_decode($charge);
//支付成功
if (isset($chargeObj->status) || $chargeObj->status == 'succeeded') {
$flowBusiness = BaseFlow::createBusinessFlow($paymentOrderInfo->business);
$result = $flowBusiness->buyGoods($paymentOrderInfo);
UserPaymentOrder::query()->where('id',$paymentOrderInfo->id)->where('state',1)->update(['state'=>3, 'succeeded_at' => date('Y-m-d H:i:s')]);
Log::info('购买结果'.json_encode($result));
return $this->format('0', '支付成功', null,'success');
}else{
//支付失败
throw new BusinessException("未支付成功");
}
}
}catch(\Exception $e){
\Log::info($e->getMessage());
return $this->format('1', '支付失败;', null,'fail');
}
}
/**
* 信用卡支付 礼包购买
* @param Request $request
* @return Json
*/
public function paidGift(Request $request){
// 验证参数
$v = Validator::make($request->all(), [
'amount' => 'required|string',
'currency' => 'required|in:sgd',
'source' => 'required',
// 'receipt_email' => 'email',
// 'order_sn' => 'required|string',
'parentNo' => 'required',
],[
'amount.required' => '支付金额必填',
'amount.string' => '支付金额必须为字符串',
'currency.required' => '货币类型必填默认sgd',
'currency.in' => '货币只有一种sgd',
'source.required' => '支付来源必填', //未保存客户银行卡信息的 只能调用stripe.js 获取token
// 'receipt_email.email' => '接收邮件格式有误',
// 'order_sn.required' => '订单ID必填',
// 'order_sn.string' => '订单ID必须为字符串',
'parentNo.required' => '推荐人号必传',
]);
if($v->fails())
{
return $this->format('1', $v->errors()->all()[0], null,'fail');
}
$paymentOrder = new UserPaymentOrder();
$business = new PaymentBusiness();
$data = $business->createxykOrder();
$orderId = $data['order_id'];
//
// $businessName = 'OrderInfo';
// $payProvider = $request->get('payProvider');
//
// $orderId = UserUpgradeOrder::where('order_sn',$request->order_sn)->value("id");
// if (!$orderId){
// return $this->format('1', $request->order_sn."支付订单不存在", null,'fail');
// }
$business = $request->get('business', 'UserUpgradeOrder');
$paymentOrderInfo = $paymentOrder->where('order_id',$orderId)->where('business', $business)->first();
if(!$paymentOrderInfo){
return $this->format('1', "支付订单不存在", null,'fail');
}elseif (in_array($paymentOrderInfo->state,[2,3])){
return $this->format('1', '已经支付', null,'success');
}
try {
//\Stripe\Stripe::setApiKey(StripePay::_getKey());
StripePay::init();
$param = [
'amount' =>_isLocal() ? 50 : $paymentOrderInfo->price*100,
'currency' => $request->currency,
'source' => $request->source,
'metadata' => [
'order_sn'=> $paymentOrderInfo->trade_no,
'amount'=> _isLocal() ? 50 : $paymentOrderInfo->price,
'business'=> $paymentOrderInfo->business,
'ordered_at' =>$paymentOrderInfo->created_at,
],
// 'customer' => $paymentOrderInfo->trade_no,
];
Log::info("start step-3");
// if ($request->has('user_id')) {
// $param['customer'] = $request->user_id;
// }
if ($request->has('receipt_email')) {
$param['receipt_email'] = $request->receipt_email;
}
//支付对象
$chargeObj = null;
Log::info("礼包 charge对象内容前:".json_encode($param));
$charge = \Stripe\Charge::create($param);
Log::info("礼包 charge对象内容:".json_encode($charge));
$charge = json_encode($charge);
if ($charge) {
$chargeObj = json_decode($charge);
//支付成功
if (isset($chargeObj->status) || $chargeObj->status == 'succeeded') {
$flowBusiness = BaseFlow::createBusinessFlow($paymentOrderInfo->business);
$result = $flowBusiness->buyGoods($paymentOrderInfo);
UserPaymentOrder::query()->where('id',$paymentOrderInfo->id)->where('state',1)->update(['state'=>3, 'succeeded_at' => date('Y-m-d H:i:s')]);
Log::info('购买结果'.json_encode($result));
return $this->format('0', '支付成功', null,'success');
}else{
//支付失败
throw new BusinessException("未支付成功","388",null);
}
}
}catch(\Exception $e){
\Log::info(__METHOD__ . $e->getMessage());
return $this->format('1', '支付失败;', null,'fail');
}
}
/**
* Notes: 创建 H5 订单
* User: lphwxl
* @param Request $request
* @return JsonResponse
* @throws BusinessException
*/
public function createWebOrd(Request $request){
$business = new PaymentBusiness();
return JsonResponse::create([
'result'=>'success',
'error'=>'0',
'msg'=>'创建订单成功!',
'data'=>$business->createxykOrder()
]);
}
/**
* 创建支付订单
* @return static
*/
public function orderToAlipay(){
$business = new PaymentBusiness();
return JsonResponse::create([
'result'=>'success',
'error'=>'0',
'msg'=>'提交成功',
'data'=>$business->createxykOrder()
]);
}
public function stripeSourceChargeable(Request $request){
//发起stripe确认支付
$data = $request->input();
try{
$charge = StripePay::sendCharge($data['data']['object']['id'],$data['data']['object']['client_secret']);
if(!$charge){
throw new BusinessException('发起确认扣款失败!,源Source:'.$data['data']['object']['id']);
}
//修改订单状态
self::_changeOrderStatus(StripePay::$_userPayOrder);
}catch(\Exception $e){
throw new BusinessException('stripe_alipay回调异常!源Source:'.$data['data']['object']['id']);
}
}
/**
* stripe webhooks 异步通知
*/
public function stripeNotify(Request $request){
StripePay::checkoutWebhookSignatures();
$data = $request->input();
try{
$usrpayObj = UserPaymentOrder::where('state','=',1)
->where('trade_no',$data['data']['object']['metadata']['order_sn'])
->where('business',$data['data']['object']['metadata']['business'])
->first();
if(!$usrpayObj)
return http_response_code(200);
//修改订单状态
self::_changeOrderStatus($usrpayObj);
}catch(\Exception $e){
\Log::info($e->getMessage());
throw new BusinessException('stripe_alipay回调异常!源Source:'.$data['data']['object']['id']);
}
}
public function stripeSourceSucceeded(Request $request){
//后期处理,邮件通知
//Log::info('stripeSourceSucceeded:'.json_encode($request->all()));
}
static private function _changeOrderStatus(UserPaymentOrder $orderObj){
try{
DB::beginTransaction();
$res = UserPaymentOrder::query()->where('id',$orderObj->id)
->where('state','=',1)
->update([
'state'=>3,
'succeeded_at'=>date('Y-m-d H:i:s')
]);
$flowBusiness = BaseFlow::createBusinessFlow($orderObj->business);
$result = $flowBusiness->buyGoods($orderObj);
if($res && $result) {
DB::commit();
}
else
DB::rollBack();
Log::info('购买结果'.json_encode($result));
}catch (\Exception $e){
DB::rollBack();
throw new BusinessException('strip回调异常!'.$e->getMessage());
}
}
}
(2)支付服务层:
namespace App\Services;
use App\Business\Exceptions\BusinessException;
use App\Business\Exceptions\OrderNotExistsException;
use App\Business\PaymentBusiness;
use App\Models\UserPaymentOrder;
class StripePay{
static private $_source = null;
static public $_userPayOrder = null;
/**
* Notes: 判断 Source源 的状态
* User: lphwxl
* @param string $sourceID
* @return \Stripe\StripeObject
*/
static public function _sourceIsExists(string $sourceID,string $client_secret){
self::init();
$source = \Stripe\Source::retrieve($sourceID,[
'api_key'=>'sk_live_xxxxxxxxxxxxxu',//self::_getKey()
'client_secret'=>$client_secret
]);
if($source && ($source instanceof \Stripe\StripeObject) && ($source->id == $sourceID)){
self::$_source = $source;
}else
throw new BusinessException('扣款失败,源source:'.$sourceID);
}
/**
* Notes: 发起 确认扣款
* User: lphwxl
* @param string $sourceID
* @param array $params
* @return null|\Stripe\ApiResource
* @throws BusinessException
* @throws OrderNotExistsException
*/
static public function sendCharge(string $sourceID,string $client_secret,array $params=[]){
self::_sourceIsExists($sourceID,$client_secret);
if(self::$_source && self::$_source->status == 'chargeable'){
self::_UserPayOrderIsExists(self::$_source->metadata['order_sn'],self::$_source->metadata['order_id']);
$param = [
'amount' => _isLocal() ? 50:self::$_userPayOrder->price*100,
'currency' => self::$_source->currency,
'source' => self::$_source->id,
'metadata' => [
'order_sn'=> self::$_userPayOrder->trade_no,
'order_id'=> self::$_userPayOrder->order_id,
'amount'=> _isLocal() ? 50: self::$_userPayOrder->price*100,
'business'=> self::$_userPayOrder->business,
'ordered_at' =>self::$_userPayOrder->created_at,
],
];
try{
$charge = \Stripe\Charge::create($param);
if(!($charge instanceof \Stripe\ApiResource)){
throw new BusinessException('确认扣款失败,源Source:'.$sourceID);
}
if($charge && $charge->status == 'succeeded'){
return $charge;
}
return null;
}catch (\Exception $e){
throw new BusinessException('确认扣款失败,源Source:'.$sourceID);
}
}else
throw new BusinessException('确认扣款失败,源Source:'.$sourceID);
}
static public function checkoutWebhookSignatures($type='ChargeSucceed'){
self::init();
$type = 'get'.$type.'Secret';
$endpoint_secret = self::$type();
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
http_response_code(400);
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400);
exit();
}
// Do something with $event
//http_response_code(200); // PHP 5.4 or greater
}
/**
* Notes: 获取 api-key
* User: lphwxl
* @return mixed
*/
static public function _getKey(){
if(_isLocal())
return config('stripe.STRIPE_API_TEST_KEY');
return config('stripe.STRIPE_API_KEY');
}
/**
* Notes: 获取 webhook 的密钥
* User: lphwxl
* @return mixed
*/
static public function getChargeSucceedSecret(){
if(_isLocal())
return config('stripe.TEST_CHARGE_SUCCEEDED_SECRET');
return config('stripe.CHARGE_SUCCEEDED_SECRET');
}
static public function init(){
\Stripe\Stripe::setApiKey('sk_live_rBxxxxxxxxTxxxxxxxxxx');
//\Stripe\Stripe::setApiKey(self::_getKey());
}
/**
* Notes: 判断支付订单是否存在
* User: lphwxl
* @param string $order_sn
* @param int $order_id
* @throws BusinessException
* @throws OrderNotExistsException
*/
static public function _UserPayOrderIsExists(string $order_sn,int $order_id){
$paymentOrder = new UserPaymentOrder();
$paymentOrderInfo = $paymentOrder->where('order_id',$order_id)
->where('trade_no',$order_sn)
->first();
if(!$paymentOrderInfo){
throw new OrderNotExistsException('stripe_alipay订单不存在!');
}elseif (in_array($paymentOrderInfo->state,[2,3])){
throw new BusinessException('stripe_alipay订单已支付!');
}
self::$_userPayOrder = $paymentOrderInfo;
}
}
?>
(3)配置信息:
<?php
return [
'STRIPE_API_TEST_KEY'=>'sk_test_fXXXXXXXXXXXXX',
'STRIPE_API_KEY'=>'sk_live_XXXXXXXXmu',
'TEST_CHARGE_SUCCEEDED_SECRET'=>'whsec_XXXXXXXXXXXXXX',
'CHARGE_SUCCEEDED_SECRET'=>'whsec_XXXXXXXXXXXXXXXXXX',
];