带有tipsi-stripe的createTokenWithCard在到期不正确时不会返回错误?

时间:2018-06-15 09:06:20

标签: react-native stripe-payments

也发布在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"

2 个答案:

答案 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回答:

  • 因此条带不会检查到期和CVC,并且即使它们不正确也会返回一个令牌
  • Firebase,当它获取要写入的条带标记时,执行以下操作:
    • 写作
    • 验证它(包括到期和CVC)
    • 如果细节正确,则会用卡片详细信息(最后4位数,品牌,国家等)替换之前写的令牌。
    • 如果过期或CVC不正确,它会将令牌留在数据库中并添加错误消息(键='错误'。"卡被拒绝"或其他消息,如果到期没问题且CVC不正确。)

因此,如果我们想知道卡验证的真实状态是什么,我们需要等到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 })
    }
  };