我正在将我的条带集成迁移到新的SCA欧洲法规。我正在将Stripe Billing与Stripe gem(https://github.com/stripe/stripe-ruby),Rails 5.2(ruby 2.6.4)配合使用。我也有turbolinks“开”。
我正在为3D安全身份验证而苦苦挣扎,Stripe.js脚本应该可以平稳地处理此问题,但是我无法提供执行该操作所需的变量。
文档说开票引擎创建了PaymentIntent,所以我不必自己创建它。该对象必须带有client_cecret,我必须将其传递给视图。我将使用gon gem(https://github.com/gazay/gon)完成此操作。要获得这个秘密,根据Stripe docs的介绍,我必须用“ latest_invoice.payment_intent”来“扩展”订阅对象,然后将“ latest_invoice.payment_intent.client_secret”传递给一个变量,此后,JavaScript将用于通过“ .handleCardPayment”以3D安全方式处理付款或2FA。
这是我registration_controller.rb的create_subscription操作(我使用devise):
def create_subscription
Stripe.api_key = Rails.application.credentials[Rails.env.to_sym][:stripe][:stripe_api_key]
plan_id = params[:plan_id]
plan = Stripe::Plan.retrieve(plan_id)
token = params[:stripeToken]
customer = if @user.stripe_id?
Stripe::Customer.retrieve(@user.stripe_id)
else
Stripe::Customer.create(email: @user.email, source: token)
end
subscription = customer.subscriptions.create(
items: [
{
plan: plan_id
}
],
expand: ['latest_invoice.payment_intent']
)
gon.intent = subscription.latest_invoice.payment_intent
options = {
stripe_id: customer.id,
stripe_subscription_id: subscription.id,
subscribed: true,
plan: plan_id
}
options.merge!(
card_last4: params[:user][:card_last4],
card_exp_month: params[:user][:card_exp_month],
card_exp_year: params[:user][:card_exp_year],
card_type: params[:user][:card_type]
) if params[:user][:card_last4]
@user.update(options)
flash[:success] = "¡Se ha creado la suscripción correctamente!"
end
然后这是我的subscriptions.js脚本:
$(document).on("turbolinks:load", function () {
const publishableKey = document.querySelector("meta[name='stripe-key']").content;
const stripe = Stripe(publishableKey);
const elements = stripe.elements({
locale: 'es'
});
const style = {
base: {
color: "#32325d",
fontWeight: 500,
fontSize: "16px",
fontSmoothing: "antialiased",
"::placeholder": {
color: "#CFD7DF"
}
},
invalid: {
color: "#E25950"
}
};
// Create an instance of the card Element.
const card = elements.create('card', { style });
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
card.addEventListener('change', ({ error }) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
// Create a token or display an error when the form is submitted.
const form = document.getElementById('new_user');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const { token, error } = await stripe.createToken(card);
if (error) {
// Inform the customer that there was an error.
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
// handle the payment (pass, pyment error or 2FA)
const clientSecret = gon.intent.client_secret;
const { paymentIntent, error } =
await stripe.handleCardPayment(
clientSecret, card, {
save_payment_method: true,
setup_future_usage: 'off_session'
}
);
if (error) {
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
// Send the token to your server.
// stripeTokenHandler(token);
const stripeTokenHandler = (token) => {
// Insert the token ID into the form so it gets submitted to the server
const form = document.getElementById('new_user');
const hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
["type", "last4", "exp_month", "exp_year"].forEach(function (field) {
addCardField(form, token, field);
});
// Submit the form
form.submit();
}
}
}
});
function addCardField(form, token, field) {
let hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', "user[card_" + field + "]");
hiddenInput.setAttribute('value', token.card[field]);
form.appendChild(hiddenInput);
}
});
在这种配置下,当我尝试使用条测试卡号获取3D安全模式时,会出现错误:
subscriptions.js:61未捕获(已承诺)TypeError:无法读取> HTMLFormElement中未定义的属性“ client_secret”。 (subscriptions.js:61)
我尝试以Stripe Doc的方式(在button标记中为数据秘密)传递变量,但遇到相同的错误(或类似错误)。
似乎很清楚该变量不存在,但是,如何正确传递它?我想念什么?
谢谢!