php - 如何正确使用付款意图,我不断收到错误无效付款意图状态

标签 php stripe-payments payment-gateway

我正在尝试实现付款意图 api,但我不断收到无效的付款意图状态,我在堆栈溢出上看到了答案,但没有帮助, 我不知道它是一个糟糕的服务器端还是客户端实现,因为我对此仍然陌生

我尝试将requires_action更改为requires_source_action,但没有任何帮助,尝试修改html,但我不知道出了什么问题。

负责,我有

<?php
  # vendor using composer
  require_once('vendor/autoload.php');

  \Stripe\Stripe::setApiKey(getenv('sk_test_HERE'));

  header('Content-Type: application/json');

  # retrieve json from POST body
  $json_str = file_get_contents('php://input');
  $json_obj = json_decode($json_str);
  //$amount=$POST['amount'];
//----------------🤒 changed the intent from null;
  $intent = null;
  try {
    if (isset($json_obj->payment_method_id)) {
      # Create the PaymentIntent
      $intent = \Stripe\PaymentIntent::create([
        'payment_method' => $json_obj->payment_method_id,
        'amount' => 1000,
        'currency' => 'eur',
        'confirmation_method' => 'manual',
        'confirm' => true,
      ]);
    }
    if (isset($json_obj->payment_intent_id)) {
      $intent = \Stripe\PaymentIntent::retrieve(
        $json_obj->payment_intent_id
      );
      $intent->confirm();
    }
    generatePaymentResponse($intent);
  } catch (\Stripe\Error\Base $e) {
    # Display error on client
    echo json_encode([
      'error' => $e->getMessage()
    ]);
  }
//--------------------updated from requires action to requires source action
  function generatePaymentResponse($intent) {
    # Note that if your API version is before 2019-02-11, 'requires_action'
    # appears as 'requires_source_action'.
    if ($intent->status == 'requires_source_action' &&
        $intent->next_action->type == 'use_stripe_sdk') {
      # Tell the client to handle the action
      echo json_encode([
        'requires_action' => true,
        'payment_intent_client_secret' => $intent->client_secret
      ]);
    } else if ($intent->status == 'succeeded') {
      # The payment didn’t need any additional actions and completed!
      # Handle post-payment fulfillment
      echo json_encode([
        "success" => true
      ]);
    } else {
      # Invalid status
      http_response_code(500);
      echo json_encode(['error' => 'Invalid PaymentIntent status']);
    }
  }
?>

在我的 JavaScript 文件中


// Create a Stripe client.
var stripe = Stripe('pk_test_HERE');

// Create an instance of Elements.
var elements = stripe.elements();

// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
  base: {
    color: '#32325d',
    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
    fontSmoothing: 'antialiased',
    fontSize: '16px',
    '::placeholder': {
      color: '#aab7c4'
    }
  },
  invalid: {
    color: '#fa755a',
    iconColor: '#fa755a'
  }
};

// Create an instance of the card Element.
var card = elements.create('card', {style: style});

// Add an instance of the card Element into the `card-element` <div>.
//                                     added an extra s for form control
card.mount('#card-elements');

// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
  var displayError = document.getElementById('card-errors');
  if (event.error) {
    displayError.textContent = event.error.message;
  } else {
    displayError.textContent = '';
  }
});

// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();

  stripe.createToken(card).then(function(result) {
    if (result.error) {
      // Inform the user if there was an error.
      var errorElement = document.getElementById('card-errors');
      errorElement.textContent = result.error.message;
    } else {
      // Send the token to your server.
      stripeTokenHandler(result.token);
    }
  });
});

// Submit the form with the token ID.
function stripeTokenHandler(token) {
  // Insert the token ID into the form so it gets submitted to the server
  var form = document.getElementById('payment-form');
  var hiddenInput = document.createElement('input');
  hiddenInput.setAttribute('type', 'hidden');
  hiddenInput.setAttribute('name', 'stripeToken');
  hiddenInput.setAttribute('value', token.id);
  form.appendChild(hiddenInput);

  // Submit the form
  form.submit();
}

这是为了收集详细信息,如果您看到任何业余的东西,请原谅我

<div class="container">
  <h2 class="my-4 text-center">Service Payments</h2>

    <form action="./charge.php" method="post" id="payment-form">
        <div class="form-row">
         <input type="text" name="first_name" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="First Name" required>
         <input type="text" name="last_name" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="Last Name" required>
         <!-- <label for="t2">What's your e-mail?</label> -->
         <input type="email" name="email" id="t2" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="Email Address" required>

         <input type="amount" name="amount" class="form-control mb-3 StripeElement StripeElement--empty" placeholder="1000 translates to 10.00" required>
         <!-- changed card element to elements with an s, form control is another possible option -->
         <input id="cardholder-name" type="text">
            <div id="card-elements" class="form-control">
            <!-- /  a Stripe Element will be inserted here. / -->
            </div>
            <!-- Used to display form errors -->
             <div id="card-errors" role="alert"></div>
        </div>
        <button  id="card-button" data-secret="<?= $intent->client_secret ?>">Submit Payment</button>

  </form>
</div>

我不断收到错误:付款意向状态无效

最佳答案

看起来您可能正在处理旧文档。您收到“无效的付款意向状态”,因为您的代码正在查找不存在的状态 requires_source_action:https://stripe.com/docs/payments/intents#intent-statuses

实际状态可能是requires_confirmation,在这种情况下,您必须在服务器上确认 PaymentIntent。然后,根据状态,您要么获得 requires_action 状态,要么获得 succeeded。您选择哪一张取决于相关卡是否需要 3DS。

由于您的 PaymentIntent 使用手动确认流程,这意味着您必须在前端和后端之间进行多次往返才能真正完成付款。我建议考虑使用自动确认。这样您只需 2 个步骤:

  1. 在服务器上创建 PaymentIntent,将客户端 key ID 传递给前端
  2. 像现在一样使用 Elements 收集付款详细信息,使用第 1 步中的客户端 key 和 Stripe.js 的 handleCardPayment 完成付款

有关该流程的更多信息:https://stripe.com/docs/payments/payment-intents/quickstart#automatic-confirmation-flow

除非您有充分的理由使用手动确认,否则我会坚持使用自动确认。

关于php - 如何正确使用付款意图,我不断收到错误无效付款意图状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57650812/

相关文章:

php - 通过 SMTP 和 PHPMailer 发送外发邮件时出现超时错误

php - 防止来自 fsockopen 的警告

go - 连接帐户并创建订阅而不是一次性付款

javascript - BrainTree Sandbox 返回验证错误 : - Unknown paymentMethodNonce

cordova - 在 iPhone 应用程序中购买实体产品

php - 在 Laravel 4 中路由到 Controller 失败

php - 如果另一个字段等于 5 或​​ 10,则不要乘以一个字段

javascript - Stripe 结帐 PAY 按钮更改文本

javascript - Stripe 形式不创建 token

java - 尝试从 Neteller 获取 OAuth 访问 token 会产生错误 : "Server returned HTTP response code: 401 for URL"