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());