简体   繁体   中英

Stripe API for multiple forms generated by wordpress loop

so i am having a bit of a situation with stripe API. I have multiple modal forms generated through wordpress's loop, i am trying to make payment for each individual form separately but for some reason my javascript only targets the first form and not others on the page

Here's the loop that generates the form

<div class="col-lg-3 col-md-4 col-xs-6 col-sm-6 col-6 col-space">
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <div class="entry-content">
        <div class="card text-center price-box">
          <div class="card-body">
            <span class="price-box__title card-title">
                <b><?php the_title() ?></b>
                <?php foreach((get_the_category()) as $category) { ?>
                  <center>
                    <?php echo $category->cat_name . ' '; ?>
                  </center>
                <?php } ?>
            </span>
            <span class="price-box__value card-text">
                $<?php echo get_the_content() ?>
            </span>
            <a href="#" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal-<?php the_ID(); ?>">Buy Now</a>
          </div>
        </div>
        <?php get_template_part( 'template-parts/payment', 'form' ); ?>
    </div><!-- .entry-content -->
</div><!-- #post-<?php the_ID(); ?> -->

This is the form code

<!-- Modal -->
<div class="modal fade" id="exampleModal-<?php the_ID(); ?>" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="bg-primary safe-checkout">
        <br>
        <span class="secure-icon">
            <img 
                src="<?php bloginfo('template_url') ?>/img/fingerprint.svg" 
                width="32" 
                height="32">
        </span>
        <h5 class="text-white text-center">
            Safe Checkout
        </h5>
    </div>
    <br><br>
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close cancel-button" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true" class="text-white">&times;</span>
        </button>
      </div>
      <?php foreach((get_the_category()) as $category) { ?>
      <center>
        <h1 class="modal-title"><?php the_title() ?> <?php echo $category->cat_name . ' '; ?></h1>
      </center>
      <?php } ?>
      <div class="modal-body">
        <form class="form-<?php the_ID(); ?>">
          <label style="position: absolute; display: none; top: -9999999px;">
            <input name="price-<?php the_ID(); ?>" id="price-<?php the_ID(); ?>" type="hidden" value="<?php echo get_the_content() ?>" style="position: absolute; display: none; top: -9999999px;" />
          </label>
          <label>
            <input name="instagram-uname-<?php the_ID(); ?>" id="insta-uname-<?php the_ID(); ?>" class="field is-empty" placeholder="zoey123" />
            <span><span><img width="24" height="24" src="<?php bloginfo('template_url') ?>/img/instagram.svg"> Instagram Username</span></span>
          </label>
      <?php if ( in_category('comments') ) { ?>
      <label>
            <textarea rows="3" cols="60" name="instagram-comments-<?php the_ID(); ?>" class="field" placeholder="Comments (1 per line)" style="max-height: 127px;" maxlength="<?php the_title() ?>"></textarea>
      <span style="height: 120px;"><span></span></span>
      </label>
      <div class="clr_100"></div>
      <?php } ?>
      <div class="clr_20"></div>
      <h6 class="sep"><span><b>Payment info</b></span></h6>
      <div class="clr_20"></div>
          <div class="row">
            <div class="col-lg-6 col-sm-12">
              <label>
            <input name="cardholder-name-<?php the_ID(); ?>" class="field is-empty" placeholder="Jane Doe" />
            <span><span><img width="30" height="30" src="<?php bloginfo('template_url') ?>/img/profile.svg"> Name</span></span>
        </label>
            </div>
            <div class="col-lg-6 col-sm-12">
              <label>
            <input class="field is-empty" type="email" placeholder="janedoe@gmail.com" />
            <span><span><img width="30" height="30" src="<?php bloginfo('template_url') ?>/img/mail.svg"> Email</span></span>
        </label>
            </div>
          </div>

          <div class="row">
            <div class="col-lg-12 col-sm-12">
        <label>
          <div id="cardnumber-element-<?php the_ID(); ?>" class="field is-empty"></div>
          <span><span><img width="32" height="32" src="<?php bloginfo('template_url') ?>/img/credit-card-back-symbol.svg"> Credit or debit card</span></span>
        </label>
      </div>
      </div>

      <div class="row">
        <div class="col-lg-8 col-8 col-sm-8">
          <label>
            <div id="card-expiry-<?php the_ID(); ?>" class="field is-empty"></div>
            <span><span><img width="32" height="32" src="<?php bloginfo('template_url') ?>/img/credit-card.svg"> Expiry Date</span></span>
          </label>
        </div>

        <div class="col-lg-4 col-4 col-sm-4">
            <label>
              <div id="card-cvc-<?php the_ID(); ?>" class="field is-empty"></div>
              <span><span><img width="32" height="32" src="<?php bloginfo('template_url') ?>/img/credit-card-with-cvv-code.svg"> CVC</span></span>
            </label>
        </div>
      </div>

      <button class="btn btn-primary btn-block btn-<?php the_ID(); ?>" type="submit">Pay $<?php echo get_the_content() ?></button>
      <div class="outcome-<?php the_ID(); ?>">
        <style type="text/css">
            .outcome-<?php the_ID(); ?> {
              float: left;
              width: 100%;
              padding-top: 8px;
              min-height: 20px;
              text-align: center;
            }

            .success-<?php the_ID(); ?>, .error-<?php the_ID(); ?> {
              display: none;
              font-size: 15px;
            }

            .success-<?php the_ID(); ?>.visible, .error-<?php the_ID(); ?>.visible {
              display: inline;
            }

            .error-<?php the_ID(); ?> {
              color: #E4584C;
            }

            .success-<?php the_ID(); ?> {
              color: #34D08C;
            }

            .success-<?php the_ID(); ?> .token-<?php the_ID(); ?> {
              font-weight: 500;
              font-size: 15px;
            }
        </style>
        <div class="error-<?php the_ID(); ?>" role="alert"></div>
        <div class="success-<?php the_ID(); ?>">
          Success! Your Stripe token is <span class="token-<?php the_ID(); ?>"></span>
        </div>
      </div>
    </form>
      </div>
      <div class="modal-footer text-center">
        <div style="width: 80%; margin: 0 auto;">
          <a href="https://stripe.com" target="_blank text-center"><img class="img-responsive" src="<?php bloginfo('template_url') ?>/img/stripe.gif" width="727" height="124" /></a>
        </div>
      </div>
    </div>
  </div>
</div>

And this is the javascript that generates the token

<script type="text/javascript">
var stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh');
  var elements = stripe.elements();

  var price = document.querySelector('#price-<?php the_ID(); ?>');
  var instagramUsername = document.querySelector('#insta-uname-<?php the_ID(); ?>');


  // Card Number Element
  var cardNumber = elements.create('cardNumber', {
    iconStyle: 'solid',
    style: {
      base: {
        iconColor: '#8898AA',
        color: '#333',
        lineHeight: '36px',
        fontWeight: 300,
        fontSize: '19px',

        '::placeholder': {
          color: '#8898AA',
        },
      },
      invalid: {
        iconColor: '#e85746',
        color: '#e85746',
      }
    },
    classes: {
      focus: 'is-focused',
      empty: 'is-empty',
    },
  });
  cardNumber.mount('#cardnumber-element-<?php the_ID(); ?>');



  // Card Expiry Element
  var cardExpiry = elements.create('cardExpiry', {
    iconStyle: 'solid',
    style: {
      base: {
        iconColor: '#8898AA',
        color: '#333',
        lineHeight: '36px',
        fontWeight: 300,
        fontSize: '19px',

        '::placeholder': {
          color: '#8898AA',
        },
      },
      invalid: {
        iconColor: '#e85746',
        color: '#e85746',
      }
    },
    classes: {
      focus: 'is-focused',
      empty: 'is-empty',
    },
  });
  cardExpiry.mount('#card-expiry-<?php the_ID(); ?>');



  // Postal Code Element
  /*var postalCode = elements.create('postalCode', {
    iconStyle: 'solid',
    style: {
      base: {
        iconColor: '#8898AA',
        color: '#333',
        lineHeight: '36px',
        fontWeight: 300,
        fontSize: '19px',

        '::placeholder': {
          color: '#8898AA',
        },
      },
      invalid: {
        iconColor: '#e85746',
        color: '#e85746',
      }
    },
    classes: {
      focus: 'is-focused',
      empty: 'is-empty',
    },
  });
  postalCode.mount('#card-postal-<?php //the_ID(); ?>');*/



  // Card CVC Element
  var cardCvc = elements.create('cardCvc', {
    iconStyle: 'solid',
    style: {
      base: {
        iconColor: '#8898AA',
        color: '#333',
        lineHeight: '36px',
        fontWeight: 300,
        fontSize: '19px',

        '::placeholder': {
          color: '#8898AA',
        },
      },
      invalid: {
        iconColor: '#e85746',
        color: '#e85746',
      }
    },
    classes: {
      focus: 'is-focused',
      empty: 'is-empty',
    },
  });
  cardCvc.mount('#card-cvc-<?php the_ID(); ?>');



  var inputs = document.querySelectorAll('input.field');
  Array.prototype.forEach.call(inputs, function(input) {
    input.addEventListener('focus', function() {
      input.classList.add('is-focused');
    });
    input.addEventListener('blur', function() {
      input.classList.remove('is-focused');
    });
    input.addEventListener('keyup', function() {
      if (input.value.length === 0) {
        input.classList.add('is-empty');
      } else {
        input.classList.remove('is-empty');
      }
    });
  });

  function setOutcome(result) {
    var successElement = document.querySelector('.success-<?php the_ID(); ?>');
    var errorElement = document.querySelector('.error-<?php the_ID(); ?>');
    successElement.classList.remove('visible');
    errorElement.classList.remove('visible');

    if (result.token) {
      // Use the token to create a charge or a customer
      // https://stripe.com/docs/charges
     // axios.defaults.headers.post["Content-type"] = "application/x-www-form-urlencoded";
      axios.post('<?php bloginfo('template_url') ?>/charge.php', JSON.stringify({
        stripeToken: result.token.id,
        amount: price.value,
      }))
      .then(function (response) {
        console.log('success');
      })
      .catch(function (error) {
        console.log('failed');
      });


      successElement.querySelector('.token-<?php the_ID(); ?>').textContent = result.token.id;
      successElement.classList.add('visible');
    } else if (result.error) {
      errorElement.textContent = result.error.message;
      errorElement.classList.add('visible');
    }
  }

  cardNumber.on('change', function(event) {
    setOutcome(event);
  });

  cardExpiry.on('change', function(event) {
    setOutcome(event);
  });

  /*postalCode.on('change', function(event) {
    setOutcome(event);
  });*/

  cardCvc.on('change', function(event) {
    setOutcome(event);
  });

  document.querySelector('.form-<?php the_ID(); ?>').addEventListener('submit', function(e) {
      e.preventDefault();
      stripe.createToken(cardNumber).then(setOutcome);
  });
  document.querySelector('.form-<?php the_ID(); ?>').addEventListener('submit', function(e){
    console.log(instagramUsername.value);
  })
</script>

I believe the backend works fine but for some reason the javascript that generates the token picks values only from the first form in the loop

But this is my charge.php

<?php
    error_reporting(E_ALL); ini_set('display_errors', 1);
    require_once('stripe-php/init.php');

    \Stripe\Stripe::setApiKey('sk_test_BQokikJOvBiI2HlWgH4olfQ2');

    $_POST = json_decode(file_get_contents('php://input'), true);


    $charge = \Stripe\Charge::create(array(
      "amount" => $_POST['price'],
      "currency" => "usd",
      "source" => $_POST['stripeToken'],
    ));
?>

I'd be forever indebted to whomever gets me out of this mess please... Thank you

So after a lot of research i finally got the answer to my question, i am going to leave it here should in case anyone bumps into the same issue, Here goes. First Off the API keys shouldn't be placed within the loop you can fix it at your header just make sure the stripe.js URL comes before it, next the javascript variables have to different same goes to some css classes up above, you can achieve this by using wordpress's native function

<?php the_ID(); ?>

Simply attach this all of your classes and variables and you're set to go

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM