#intelligence-applepay-manual
1 messages · Page 1 of 1 (latest)
Thank you!
so this depends on a few things but mainly yes that your JSON formatting is not correct
let's start here
why are you making the /v1/tokens request manually? and where from? (iOS native? web?)
Okay,... not sure about the why question... it's a custom application..........
sure but where is the custom application built
is it an iOS app? a web app? a desktop app?
Let me give some details
It's PHP based, with a Javascript frontend. The JS front end sends the token to the backend which is where the CURL call to the Stripe server takes place to exchange the token
ok so it is web based
how are you implementing Apple Pay? via Apple Pay JS library?
No. Full manual
why?
Because
I can provide you with a transaction reference, if you can check my POST request for me please
From what I understand I can also run the /v1/tokens request from the browser as long as I supply the publishable key in the header... so I may try that as an alternate
Thanks for your time looking into this
sorry I'm not questioning why you're making a request to /v1/tokens
I'm asking why doing it manually
and not using PaymentRequest Button
which is the recommended and simplest way to do Apple Pay with Strie
Stirpe
okay, thanks for your concern, but it's not relevant here.....
there are a lot of custom applications out there where dependencies are not used
I've paid enough and my client has paid way more than me, in service fees, to Stripe so that we can just use the API as we wish
And as a customer for years this is the only time I've had an issue with the API lacking documentation for a feature that is part of transactional payment flow
sure but that seems irrelevant, I'm not asking you to pay more to use PaymentRequest Button!
I'm just saying, you're using a really niche part of the product becuase there's a pre-built UI component for you that does Apple Pay -> Stripe Token for you.
No, but like, not every project can use that library
So there are going to be edge cases where pk_token to stripe_token call is necessary
I tried it in the github/stripe-php library but bypassed the library in order to eliminate potential blindspots in troubleshooting
So there are going to be edge cases where pk_token to stripe_token call is necessary
I think we're misunderstanding each other
why would there be edge cases where you don't use PaymentRequest Button?
have you looked into that?
any website that can use JS can use Stripe.js and hence PaymentRequest Button
(and all websites using Stripe should from a PCI compliance perspective)
That's a fundamental property of the internet 🙂
Yup and we are PCI compliant
So could you please look into a reference transaction I have in the logs?
I can DM you the identifiers
But before I DM you them, is that in your scope of power--can you see them?
Yup and we are PCI compliant
ah ok
So there are going to be edge cases where pk_token to stripe_token call is necessary
sure but that doesn't change my answer, PRButton calls the /v1/tokens endpoint for you, if there are edge cases, Stripe has handled them for you
again, let's disagree and debug the actual request
here is what I need you to do so I can look into the actual params you pass (cause certain params are redacted on my end like the entire pk_token param)
I can provide a the token sample from a dev log
1/ make a new /v1/tokens request but whatever you pass in the pk_token: param, pass the exact same thing as pk_token_dummy: param
and then send me the Request ID from https://dashboard.stripe.com/test/logs/
I can provide a the token sample from a dev log
I'll need a new one with the addition above
ok no problem, give me about five minutes
DM'd, thanks for looking
I realize that but just doing so as not to link my account with my clients in public, that's all
it won't though as no one can look up the request ID aside from someone who works at Stripe and has the right set permissions i.e. my team who operates here on Discord
ah perfect I see the request, lemme refresh my memory on what that pk_token hash should contain, I think you're sending the whole object when you want to send just the field, checking
thank you
what are you doing with the PKToken values on your end? before passing it under pk_token
the value in pk_token is not correctly base64 encoded
e.g. I'm seeing white spaces and \\ characters in the string so something is off there
I saw the whitespace characters too. Didn't look correct. Will paste some code
markdown test
you can do three backticks for code too
like
console.log("hello")
yeah i was just making sure it worked, not familiar with discord
it's taking me a few minutes to put together a snippet, standby
I have to pay for discord to send long messages....
<script>
apple_pay_info = {};
ap.onpaymentauthorized = (( event ) => {
try {
console.log( 'onpaymentauthorized' );
console.log( JSON.stringify( event.payment ) );
apple_pay_info = event.payment;
form_submit();
}
});
function form_submit() {
// Submit form and pk_token
payload = {
form : {},
payment : {
token : apple_pay_info
}
}
// XHR POST request to our server
}
</script>```
$apple_pay_token = json_decode( $_POST[ 'payload' ][ 'payment' ][ 'token' ] );
$pk_token = json_encode( $apple_pay_token[ 'paymentData' ] );
$array = [
'pk_token' => $pk_token,
'pk_token_dummy' => $pk_token,
'pk_token_transaction_id' => $apple_pay_token[ 'transactionIdentifier' ],
'pk_token_payment_network' => $apple_pay_token[ 'paymentMethod' ][ 'network' ],
'pk_token_instrument_name' => $apple_pay_token[ 'paymentMethod' ][ 'displayName' ]
];
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL , 'https://api.stripe.com/v1/tokens' );
curl_setopt( $ch, CURLOPT_PROTOCOLS , CURLPROTO_HTTPS );
curl_setopt( $ch, CURLOPT_HTTPHEADER , [
'Authorization: Bearer ' . $stripe_api_key,
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt( $ch, CURLOPT_POST , 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS , http_build_query( $array ) );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$response = curl_exec( $ch );
?>```
(removed some debug stuff)
I have to pay for discord to send long messages....
oh TIL, I've only used Discord for Stripe work so I probably have Discord benefits/QoL features that I'm not aware of
that's all right, I think it's a great way to make money
try using utf8.encode so
$pk_token = utf8.encode( $apple_pay_token[ 'paymentData' ]);```
instead of
$pk_token = json_encode( $apple_pay_token[ 'paymentData' ] );
for reference: https://pastebin.com/YrjaFV8c
this is what your pk_token param should look like so you can use that as a reference
Error, this is a private paste or is pending moderation. If this paste belongs to you, please login to Pastebin to view it.
Thanks, however the utf8_encode function built into PHP works only on strings.
I'm implementing a javascript call using our public key to the /tokens endpoint, to have the device do this. That way, we can just send a Stripe token into our system and simplify the process. It may work using this method versus the other. I have verified that the Apple Pay key is different between the device and what I receive in my POST data.
however the utf8_encode function built into PHP works only on strings.
oh wait you're in PHP land ... sorry
I'm implementing a javascript call using our public key to the /tokens endpoint, to have the device do this.
yep that would work
so which one are you doing, client-side or server-side in PHP?
Server side php
I'm going to shift gears and try this method. Will leave this chat open in case of any continuation
here's a heavily redacted/trimmed version of what pk_token should look like:
pk_token="{\"version\":\"EC_v1\",\"data\":\"luaIKmCnRj6gaZvh16W/ax0hR2QSduQ==\",\"signature\":\"MIAGCSqGSIMn+jyDTK4pQx76g4b4/HSCU/LmEgSKAAAAAAAAA==\",\"header\":{\"ephemeralPublicKey\":\"MFkwokRN3XpOsr3OTR5SCnymtNGm7+vy4oW6W6/fu7oZSeiH5NKL2pYZ6ogCBxOcA==\",\"publicKeyHash\":\"kcExetztJN3qV9QrqohW8M=\",\"transactionId\":\"d88ecfbd1ef6e1a6f56217595b6\"}}"
though data and signature are going to be really long fields
just to calrify:
I'm implementing a javascript call using our public key to the /tokens endpoint, to have the device do this.
you mentioned this but then
Server side php
those are opposite no
you can make this call from your JS code directly to /v1/tokens too
so no, the webserver is running nginx + php, with the front-end using some javascript libraries, as this is a web app
cross-platform, cross-browser, that kind of deal
but excellent, i am not sure why I didn't think of it in the first place, I suppose the logic is to have the server translate the token to catch errors (easierly)
exchange_token = (( apple_token ) => {
return new Promise(( resolve, reject ) => {
try {
console.log( 'exchange token' );
url = 'https://api.stripe.com/v1/tokens';
delete request;
request = new XMLHttpRequest();
token = new URLSearchParams({
'pk_token' : JSON.stringify( apple_token.paymentData ),
'pk_token_dummy' : JSON.stringify( apple_token.paymentData ),
'pk_token_transaction_id' : apple_token.transactionIdentifier,
'pk_token_payment_network' : apple_token.paymentMethod.network,
'pk_token_instrument_name' : apple_token.paymentMethod.displayName
});
console.log( JSON.stringify( token.toString() ) );
request.onload = (() => {
console.log( request.responseText );
resolve( JSON.parse( request.responseText ) );
});
request.onerror = reject;
request.open( 'POST', url );
request.setRequestHeader( 'Authorization', 'Bearer ' + stripe_pk );
request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
request.send( token.toString() );
}
catch( e ) {
console.error( e );
}
});
});
Working exchange_token function, for the record, and for other eyes searching
hurrayy! so glad to hear you got it working
thanks. I've got an invalid cert issue at the moment but it's probably unreleated
Overall I'm satisfied with the quality of Stripe documentation -- I generally have no issues. I do think there's room for additional details on this type of transaction within the /tokens endpoint -- perhaps a section dedicated to exchanging an Apple Pay token and explaining the various idiosyncrasies related to data types within this transaction.
That's fair - I'll raise that as feedback to the team. In general, we don't really surface the details of this flow (exchanging the apple pay token) since it's not something we recommend often and we don't want new users stumbling upon it.
I'd just put a notice that it's for Advanced Users Only or something