5
votes

I am using stripes "Payment Request Button" to implement Apple Pay for my website. On the stripe side of things all is well. The token is passed through correcty as I verified within Stripe logs. https://stripe.com/docs/stripe-js/elements/payment-request-button

However, I get an error message: "Payment Not Completed" from Apple Pay every time I try to complete a test payment.

This has me stuck and I'm not sure how to debug or fix. Any ideas?

I get an undefined token

This is the error:

enter image description here

My set up:

FRONT END:

<script src="https://js.stripe.com/v3/"></script>
<div id="payment-request-button">
  <!-- A Stripe Element will be inserted here. -->
</div>



<script>
var stripe = Stripe('pk_test_xxxxx');

var paymentRequest = stripe.paymentRequest({
  country: 'US',
  currency: 'usd',
  total: {
    label: 'JobQuiz',
    amount: 999,
  },
  requestPayerName: true,
  requestPayerEmail: false,
});


var elements = stripe.elements();
var prButton = elements.create('paymentRequestButton', {
  paymentRequest: paymentRequest,
});

// Check the availability of the Payment Request API first.
paymentRequest.canMakePayment().then(function(result) {
  if (result) {
    prButton.mount('#payment-request-button');
  } else {
    document.getElementById('payment-request-button').style.display = 'none';
  }
});

   paymentRequest.on('token', function(ev) {
  // Send the token to your server to charge it!
    fetch('/apple-pay', {
    method: 'POST',
    body: JSON.stringify({token: ev.token.id}),
    headers: {'content-type': 'application/json'},
  })
  .then(function(response) {
    if (response.ok) {
      // Report to the browser that the payment was successful, prompting
      // it to close the browser payment interface.
      ev.complete('success');
    } else {
      // Report to the browser that the payment failed, prompting it to
      // re-show the payment interface, or show an error message and close
      // the payment interface.
      ev.complete('fail');
    }
  });
});

</script>

Server side code in app.js

app.post('/apple-pay', function(req, res, next) {


// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
var stripe = require("stripe")("sk_test_xxxxxx");

// Token is created using Checkout or Elements!
// Get the payment token ID submitted by the form:
const token = req.body.token; // Using Express

const charge = stripe.charges.create({
  amount: 999,
  currency: 'usd',
  description: 'Example charge',
  source: token,
}, function(err, charge){ 
if (err){

} else { 

}
});
});
1
Can you clarify the error? Does it appear inside of the Apple Pay modal or does it appear later from Stripe? This flow looks correct to me.korben
On the phone, at apple pay, instead of getting a checkmark indicating successful payment - I get a "Payment Not Completed' error.AndrewLeonardi
Any idea @korben?AndrewLeonardi
You need to actually setup an endpoint to accept the token created by Apple Pay at /charges that uses that token to create a charge ( stripe.com/docs/api#create_charge ).korben
@korben - thank you!!! Any chance you can point me in the direction on how to correctly do that with node?AndrewLeonardi

1 Answers

4
votes

Finally solved this. It ended up being an issue with my bodyParser set up. This explains why token was being passed though empty. I had neglected to include app.use(bodyParser.json()); below...

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());