李帅

1.打印苹果日志

......@@ -43,12 +43,15 @@ class PayController extends Controller
$order_sn = $request->post('order_sn');
$pay_type = $request->post('pay_type');
$token = $request->post('token');
$others = $request->post('others',[]);
$transactionId = $others['apple']['transactionIdentifier'];
$originalTransactionId = $others['apple']['originalTransactionIdentifier'];
$order = Order::query()->where('order_sn', $order_sn)->first();
if ($order->status != Order::UNPAID) return Response::fail('订单错误!');
$payment = $factory->init($pay_type)->verify($order, $token);
$payment = $factory->init($pay_type)->verify($order, $token, $transactionId, $originalTransactionId);
if ($payment) return Response::success(['order_sn' => $order_sn], '支付成功');
else return Response::fail('订单错误!');
......
......@@ -14,6 +14,12 @@ class UserProfile extends Model
protected $fillable = ['user_id','unionid'];
const IS_VIP = 1;
const NO_VIP = 0;
const WAIT_VIP = 2; // 已付款,等待处理(回调不及时,需要等待)
public function user()
{
return $this->belongsTo('App\Models\User', 'id', 'user_id');
......
......@@ -55,23 +55,28 @@ class ApplePayment implements PaymentInterface
// 4. 验证成功,返回true
$client = new Client(['headers' => ['Content-Type' => 'application/json']]);
try{
$response = $client->post(self::IS_SANDBOX ? self::SANDBOX_URL : self::VERIFY_URL,
['json' => ['receipt-data' => $token, 'password' => self::PASSWORD]])->getBody()->getContents();
$resp = json_decode($response,true);
Log::debug($response);
if ($resp['status'] <= 21003) {
$newToken = str_replace('+', ' ', $token);
try{
try {
$response = $client->post(self::IS_SANDBOX ? self::SANDBOX_URL : self::VERIFY_URL,
['json' => ['receipt-data' => $newToken, 'password' => self::PASSWORD]])->getBody()->getContents();
Log::debug('======== 替换+ ========');
['json' => ['receipt-data' => $token, 'password' => self::PASSWORD]])
->getBody()->getContents();
$resp = json_decode($response, true);
if ($resp['status'] > 0) {
Log::debug($response);
}catch (GuzzleException $exception){
Log::error($exception->getMessage() . 'Line:' . $exception->getLine());
}
return false;
}
}catch (GuzzleException $exception){
$originalTransactionId = $resp['receipt']['pending_renewal_info']['originalTransactionId'];
// 绑定order 和 originalTransactionId
$order->pay_number = $originalTransactionId;
$order->status = Order::PAID;
$order->save();
// 修改用户状态
$profile = UserProfile::query()->find($order->user_id);
$profile->is_vip = UserProfile::WAIT_VIP;
$profile->save();
return true;
} catch (GuzzleException $exception) {
Log::error($exception->getMessage() . 'Line:' . $exception->getLine());
}
......@@ -93,16 +98,21 @@ class ApplePayment implements PaymentInterface
Log::debug('sandbox返回的数据:====================');
$components = explode('.',$string);
if (count($components) < 3){
Log::error("jwt错误");
return false;
}
$header = json_decode(base64_decode($components[0]),true);
// 这一步可以省略,不需要验证根证书
$this->validateAppleRootCa($header);
// $this->validateAppleRootCa($header);
$responseBodyPayload = $this->decodeCertificate($string, $header['x5c'][0]);
$signedTransactionInfoString = $responseBodyPayload->data->signedTransactionInfo;
$components = explode('.',$signedTransactionInfoString);
$header = json_decode(base64_decode($components[0]),true);
$signedTransactionInfo = $this->decodeCertificate($signedTransactionInfoString, $header['x5c'][0]);
$responseBodyPayload->data->signedTransactionInfo = $signedTransactionInfo;
$signedRenewalInfoString = $responseBodyPayload->data->signedRenewalInfo;
$components = explode('.',$signedRenewalInfoString);
$header = json_decode(base64_decode($components[0]),true);
$signedRenewalInfo = $this->decodeCertificate($signedRenewalInfoString, $header['x5c'][0]);
$responseBodyPayload->data->signedRenewalInfo = $signedRenewalInfo;
Log::debug(print_r($responseBodyPayload,true));
/**{
"notificationType": "SUBSCRIBED"
......@@ -112,26 +122,7 @@ class ApplePayment implements PaymentInterface
"bundleId": "ink.parlando.parlando"
"bundleVersion": "13"
"environment": "Sandbox"
"signedTransactionInfo": "xxx"
"signedRenewalInfo": "xxx"
}
"version": "2.0"
"signedDate": 1671451705697
}
*/
$signedTransactionInfoString = $responseBodyPayload->data->signedTransactionInfo;
$components = explode('.',$signedTransactionInfoString);
$header = json_decode(base64_decode($components[0]),true);
if (count($components) < 3){
Log::error("jwt错误");
return false;
}
$signedTransactionInfo = $this->decodeCertificate($string, $header['x5c'][0]);
Log::debug(print_r($signedTransactionInfo,true));
$responseBodyPayload->data->signedTransactionInfo = $signedTransactionInfo;
/**{
"signedTransactionInfo": {
"transactionId": "2000000231419425"
"originalTransactionId": "2000000229164150"
"webOrderLineItemId": "2000000017115109"
......@@ -146,18 +137,8 @@ class ApplePayment implements PaymentInterface
"inAppOwnershipType": "PURCHASED"
"signedDate": 1671451705700
"environment": "Sandbox"
}*/
$signedRenewalInfoString = $responseBodyPayload->data->signedRenewalInfo;
$components = explode('.',$signedRenewalInfoString);
$header = json_decode(base64_decode($components[0]),true);
if (count($components) < 3){
Log::error("jwt错误");
return false;
}
$signedRenewalInfo = $this->decodeCertificate($string, $header['x5c'][0]);
Log::debug(print_r($signedRenewalInfo,true));
$responseBodyPayload->data->signedRenewalInfo = $signedRenewalInfo;
/**{
"signedRenewalInfo": {
"originalTransactionId": "2000000229164150"
"autoRenewProductId": "monthly_yiyan_vip"
"productId": "monthly_yiyan_vip"
......@@ -165,8 +146,79 @@ class ApplePayment implements PaymentInterface
"signedDate": 1671451705673
"environment": "Sandbox"
"recentSubscriptionStartDate": 1671451694000
}
}
"version": "2.0"
"signedDate": 1671451705697
}*/
Log::debug(print_r($responseBodyPayload,true));
switch ($responseBodyPayload->notificationType){
case "SUBSCRIBED":
if ($responseBodyPayload->subtype == 'INITIAL_BUY'){ //首次购买
}
if ($responseBodyPayload->subtype == 'RESUBSCRIBE'){ //重新订阅
// 应该再创建一个订单。。。
}
$originalTransactionId = $responseBodyPayload->data->signedTransactionInfo->originalTransactionId;
$order = Order::query()->where('pay_number', $originalTransactionId)->first();
if(!$order) {
Log::error('没有找到对应的订单,说明apple服务端比客户端的回调快!');
return;
}
/** 修改订单状态*/
$order->pay_time = Carbon::now();
$order->pay_type = $responseBodyPayload->data->signedTransactionInfo->type;
$order->save();
/** 给用户加会员*/
$user = UserProfile::query()->find($order->user_id);
$user->is_vip = 1;
$user->create_vip_time = Carbon::createFromTimestampMs($responseBodyPayload->data->signedTransactionInfo->purchaseDate);
$user->expire_vip_time = Carbon::createFromTimestampMs($responseBodyPayload->data->signedTransactionInfo->expiresDate);
$user->buy_number += 1;
$user->buy_amount += $order->pay_amount;
$user->last_buy_time = Carbon::now();
$user->save();
break;
case "DID_RENEW":
// 应该再创建一个订单。。。
$originalTransactionId = $responseBodyPayload->data->signedTransactionInfo->originalTransactionId;
$order = Order::query()->where('pay_number', $originalTransactionId)->first();
if(!$order) {
Log::error('没有找到对应的订单,说明apple服务端比客户端的回调快!');
return;
}
/** 给用户加会员*/
$user = UserProfile::query()->find($order->user_id);
$user->is_vip = 1;
$user->expire_vip_time = Carbon::createFromTimestampMs($responseBodyPayload->data->signedTransactionInfo->expiresDate);
$user->buy_number += 1;
$user->buy_amount += $order->pay_amount;
$user->last_buy_time = Carbon::now();
$user->save();
break;
case "EXPIRED":
// 应该再创建一个订单。。。
$originalTransactionId = $responseBodyPayload->data->signedTransactionInfo->originalTransactionId;
$order = Order::query()->where('pay_number', $originalTransactionId)->first();
if(!$order) {
Log::error('没有找到对应的订单,说明apple服务端比客户端的回调快!');
return;
}
/** 给用户取消会员*/
$user = UserProfile::query()->find($order->user_id);
$user->is_vip = 0;
$user->expire_vip_time = Carbon::createFromTimestampMs($responseBodyPayload->data->signedTransactionInfo->expiresDate);
$user->save();
break;
default:
Log::debug('特殊通知类型:'.$responseBodyPayload->notificationType.' ====================');
Log::debug(var_export($responseBodyPayload,true));
}
}
private function validateAppleRootCa($header)
......