Toggle navigation
Toggle navigation
This project
Loading...
Sign in
OnePoem
/
OnePoem-Server
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
李帅
2022-12-20 00:56:46 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f416d2a13b4ce93b1cbda26bed714273b0beb439
f416d2a1
1 parent
70d44ae9
1.打印苹果日志
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
120 additions
and
4 deletions
app/Payment/ApplePayment.php
public/AppleRootCA-G3.pem
app/Payment/ApplePayment.php
View file @
f416d2a
...
...
@@ -13,16 +13,19 @@ use App\Models\Order;
use
App\Models\User
;
use
App\Models\UserProfile
;
use
Carbon\Carbon
;
use
Firebase\JWT\SignatureInvalidException
;
use
GuzzleHttp\Client
;
use
Illuminate\Support\Facades\Log
;
use
Illuminate\Support\Facades\Redis
;
use
Firebase\JWT\JWT
;
use
Firebase\JWT\Key
;
use
Illuminate\Support\Facades\File
;
class
ApplePayment
implements
PaymentInterface
{
const
IS_SANDBOX
=
true
;
const
CA_PATH
=
"/AppleRootCA-G3.pem"
;
public
function
__construct
()
{
...
...
@@ -48,7 +51,6 @@ class ApplePayment implements PaymentInterface
public
function
notifySandbox
(
$string
)
{
Log
::
debug
(
'sandbox返回的数据:===================='
);
Log
::
debug
(
$string
);
$components
=
explode
(
'.'
,
$string
);
if
(
count
(
$components
)
<
3
){
...
...
@@ -58,6 +60,105 @@ class ApplePayment implements PaymentInterface
$header
=
json_decode
(
base64_decode
(
$components
[
0
]),
true
);
Log
::
debug
(
print_r
(
$header
,
true
));
// 这一步可以省略,不需要验证根证书
$this
->
validateAppleRootCa
(
$header
);
$responseBodyPayload
=
$this
->
decodeCertificate
(
$string
,
$header
[
'x5c'
][
0
]);
Log
::
debug
(
print_r
(
$responseBodyPayload
,
true
));
/**{
"notificationType": "SUBSCRIBED"
"subtype": "RESUBSCRIBE"
"notificationUUID": "99e65e59-c178-4f49-8b83-ea7d916cb568"
"data": {
"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
));
/**{
"transactionId": "2000000231419425"
"originalTransactionId": "2000000229164150"
"webOrderLineItemId": "2000000017115109"
"bundleId": "ink.parlando.parlando"
"productId": "monthly_yiyan_vip"
"subscriptionGroupIdentifier": "21080623"
"purchaseDate": 1671451694000
"originalPurchaseDate": 1671123372000
"expiresDate": 1671451994000
"quantity": 1
"type": "Auto-Renewable Subscription"
"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
));
/**{
"originalTransactionId": "2000000229164150"
"autoRenewProductId": "monthly_yiyan_vip"
"productId": "monthly_yiyan_vip"
"autoRenewStatus": 1
"signedDate": 1671451705673
"environment": "Sandbox"
"recentSubscriptionStartDate": 1671451694000
}*/
}
private
function
validateAppleRootCa
(
$header
)
{
$lastIndex
=
count
(
$header
[
'x5c'
])
-
1
;
$certificate
=
$this
->
getCertificate
(
$header
[
'x5c'
][
$lastIndex
]);
if
(
$certificate
!=
File
::
get
(
public_path
(
self
::
CA_PATH
)))
return
false
;
return
true
;
}
private
function
getCertificate
(
$string
)
{
$certificate
=
"-----BEGIN CERTIFICATE-----"
.
PHP_EOL
;
$certificate
.=
chunk_split
(
$string
,
64
,
PHP_EOL
);
$certificate
.=
"-----END CERTIFICATE-----"
.
PHP_EOL
;
return
$certificate
;
}
private
function
decodeCertificate
(
$string
,
$appleCertificate
)
{
$certificate
=
$this
->
getCertificate
(
$appleCertificate
);
$cert_object
=
openssl_x509_read
(
$certificate
);
$pkey_object
=
openssl_pkey_get_public
(
$cert_object
);
$pkey_array
=
openssl_pkey_get_details
(
$pkey_object
);
$public_key
=
$pkey_array
[
"key"
];
try
{
$decode
=
JWT
::
decode
(
$string
,
new
Key
(
$public_key
,
"ES256"
));
return
(
array
)
$decode
;
}
catch
(
SignatureInvalidException
$exception
){
Log
::
error
(
"Signature Invalid!"
);
return
false
;
}
}
}
\ No newline at end of file
...
...
public/AppleRootCA-G3.pem
0 → 100644
View file @
f416d2a
-----BEGIN CERTIFICATE-----
MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS
QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u
IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN
MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS
b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y
aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49
AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf
TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517
IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA
MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4
at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM
6BgD56KyKA==
-----END CERTIFICATE-----
Please
register
or
login
to post a comment