Tom Oakley
Tom Oakley

Reputation: 6403

Submit Stripe and custom form at the same time

I Have a form and details embedded in it. The form is submitted by AJAX. A part of the form is a Stripe payment form. When I click but submit button, I want Stripe to check the details are correct, but not submit the charge, until the rest of the form has been checked and submitted. Then the Stripe payment can be submitted.

Here is my code for the form submissions (written myself, massively simplified):

JS:

$(".booking-form").submit(function(e) {
  e.preventDefault();
  // JavaScipt form validation stuff. If all correct, submit form via AJAX
  var data = $(".form").serialize();
  $.post(bookingDetails.ajaxurl, data, function(response) {
    if (response['data'] == "success") {
      // Show some stuff to the user that confirms the submission, etc
    } 
  });
});

PHP:

function sendData() {
  $name = $_POST['name'];
  $email = $_POST['email'];
  $to = "[email protected]";
  $subject = "New email";
  $message = "New Email contents";

  if ( (!empty($name)) && (!empty($email)) ) { // check that fields have data before submitting
    $mail = mail($to, $subject, $message, $headers);
    wp_send_json_success("success"); // yes, this site runs on WordPress
  } 
}

And the Stripe stuff (from the wp-stripe plugin, but happy to edit it or whatever)

JS:

function stripeResponseHandler(status, response) {
  if (response.error) {
    $(".payment-errors").show().html(response.error.message);
  } else {
    var form$ = $("#wp-stripe-payment-form");
    var token = response['id'];
    form$.append("<input type='hidden' name='stripeToken' value='" + token + "' />");

    var newStripeForm = form$.serialize();

    $.ajax({
      type : "post",
      dataType : "json",
      url : ajaxurl,
      data : newStripeForm,
      success: function(response) {
        $('.wp-stripe-details').prepend(response);
      }
    });
  }
}

$("#wp-stripe-payment-form").submit(function(event) {
  event.preventDefault();
  $(".wp-stripe-notification").hide();
  var amount = $('.total-vat').val() * 100; //amount you want to charge
  Stripe.createToken({
      name: $('.wp-stripe-name').val(),
      number: $('.card-number').val(),
      cvc: $('.card-cvc').val(),
      exp_month: $('.card-expiry-month').val(),
      exp_year: $('.card-expiry-year').val()
  }, stripeResponseHandler);
  if (paymentSuccessful) {
    console.log("the payment was successful");
  }
  return false; // prevent the form from submitting with the default action
}

So my question is, how do I integrate the Stripe stuff and my custom stuff?

Upvotes: 2

Views: 3057

Answers (1)

Tom Oakley
Tom Oakley

Reputation: 6403

I found the answer to this; here is how I combined my own form info and Stripe's payment data to be processed at the same time with AJAX.

The PHP:

\Stripe\Stripe::setApiKey("YOUR_SECRET_KEY");

function wp_stripe_charge($amount, $card, $email) {
   $charge = array(
    'card' => $card,
    'amount' => $amount,
    'currency' => 'gbp',
    'receipt_email' => $email
  );

  $response = \Stripe\Charge::create($charge);

  return $response;
}

function sendData() {
  // add any variables which you passed from the form here
  $total = $_POST['total-vat'];
  $amount = str_replace('$', '', $total) * 100;
  $card = $_POST['stripeToken'];
  try {
    $payment = wp_stripe_charge($amount, $card, $bEmail);
  } catch(\Stripe\Error\Card $e) {
    $payment = false;
    $errorJSON = $e->getJsonBody();
    $error = $errorJSON['error'];
  }

  // do a whole load of stuff to submit my own form, including checking if order was successful, etc

  $return = array(); // add whatever data to this to return to the JavaScript

  echo json_encode($return);
}

The JavaScript:

$(".booking-form").submit(function(event) {
  event.preventDefault();
  // do any validation checks or other actions here
  var amount = $('.total-vat').val() * 100, //amount you want to charge
      name = $('.booking-name').val();
  Stripe.createToken({
      name: name,
      number: $('.card-number').val(),
      cvc: $('.card-cvc').val(),
      exp_month: $('.card-expiry-month').val(),
      exp_year: $('.card-expiry-year').val(),
      address_line1: $(".booking-address-1").val(),
      address_line2: $(".booking-address-2").val(),
      address_city: $(".booking-city").val(),
      address_state: $(".booking-county").val(),
      address_zip: $(".booking-postcode").val()
  }, stripeResponseHandler);
  return false;
});


function stripeResponseHandler(status, response) {
  if (response.error) {
    $(".payment-errors").show().html(response.error.message);
  } else {
    var token = response['id'];
    $(".stripe-payment-form").append("<input type='hidden' name='stripeToken' value='" + token + "' />");
    formSubmission(); // if form has no errors and Stripe has verified it too, go ahead with making payment
  }
}

function formSubmission() {
  var data = $(form).serialize(); // plus any other data that may be held in a variable or something here
  $.post(ajaxUrl, data, function(response) {
    // add your response messages, actions etc here
  }
});

Stripe has an extensive API and will return various error codes or success messages based on what happened when the payment was processed. For example:

(these are PHP variables)

$payment->status == "succeeded" / "failed"
$payment->id

$error['code'] == 'card_declined' / 'incorrect_cvc' / 'expired_card' / 'processing_error'

you can view more at https://stripe.com/docs/api.

Hope that helps. Happy to try and help to answer any questions!

Upvotes: 2

Related Questions