也发布在https://github.com/tipsi/tipsi-stripe/issues/312
#menu-primary li a {
padding: 0px 14px;
}
我使用不正确的过期日期调用createTokenWithCard,它似乎没有返回错误,但返回一个令牌。 然后,当我尝试将此令牌写入firebase时,我看到一个错误:“您的卡被拒绝了。” tipsi-stripe会返回错误而我没有正确检查它吗?
"firebase": "^4.12.0",
"react": "^16.2.0",
"react-native": "^0.53.3",
"react-native-firebase": "^3.2.7",
"react-stripe-elements": "^1.6.0",
"tipsi-stripe": "^5.2.1"
答案 0 :(得分:2)
当您说“错误的到期日期'”时,您的意思是有效日期(即不是过去的日期),而不是与卡本身匹配的日期?假设你这样做:
当您致电stripe.createTokenWithCard
时,Stripe仅会检查这些值是否有效,例如卡号通过luhn检查,过期日期是将来。在标记化时,没有对实际卡进行实时验证。因此,即使到期时间与真实卡不匹配,也可以创建令牌。
稍后,当您将卡附加到客户时(当您调用/stripe_customers/${uid()}/sources
端点时,我认为),Stripe将对真实卡执行$ 0 / $ 1授权,此时您将如果失效日期错误,那就会下降 - 这就是你所看到的。
[0] - https://en.wikipedia.org/wiki/Luhn_algorithm
[1] - https://stripe.com/docs/saving-cards#saving-credit-card-details-for-later
答案 1 :(得分:0)
添加到@karllekko回答:
因此,如果我们想知道卡验证的真实状态是什么,我们需要等到firebase用最终细节替换初始令牌。这可能需要几秒钟。
仅用于测试目的,这是执行此操作的修改后的代码(最终代码可能会在之后检查状态,或者在短时间内睡眠,然后检查数据库中的值等,直到最终值为止集):
try {
const tokenObject = await stripe.createTokenWithCard({
number, expMonth, expYear, cvc
});
const id = firebase.database().ref().push().key;
const body = { token: tokenObject.tokenId };
firebase
.database()
.ref(`/stripe_customers/${uid()}/sources`).child(id)
.set(body)
.then(() => {
console.log("sleeping for a while");
this.sleep(15000); // delay, waiting for firebase to update
firebase
.database()
.ref(`/stripe_customers/${uid()}/sources/${id}`).once('value')
.then((snapshot) => {
const dataAfterValidation = snapshot.val();
if (dataAfterValidation) { // not null
if (dataAfterValidation.hasOwnProperty('error')) {
// card invalid
console.log("Card declined. Check expiration date and CVC.");
} else if (dataAfterValidation.hasOwnProperty('brand')) {
console.log("Card added to the database.");
} else {
// still not updated
console.log("Card is being validated.");
}
} else {
console.log("Hmmm... Should not reach here...");
}
});
this.setState({ addingCardInProcess: false });
})
.catch((err) => {
this.setState({ addingCardInProcess: false });
console.log("FAILURE", err.message);
});
} catch(err) {
console.log("FAILURE", err.message);
this.setState({ addingCardInProcess: false })
}
};