Flutter stripe_payment Native pay 不收费(Apple Pay and Google Pay)

Flutter stripe_payment Native pay not charged(Apple Pay and Google Pay)

条纹支付API调用return状态200但未扣款

我有一个 Flutter 应用程序使用 Stripe 支付。

我完成了:

  1. 证书已创建。
  2. 商家 ID 已创建。

按照 stripe_payment 的例子,我的本地支付方式如下:

void _handleNativePayment(String amount) async {
    Token token = await StripePayment.paymentRequestWithNativePay(
      androidPayOptions: AndroidPayPaymentRequest(
        totalPrice: amount,
        currencyCode: _currencyCode,
      ),
      applePayOptions: ApplePayPaymentOptions(
        countryCode: _countryCode,
        currencyCode: _currencyCode,
        items: [
          ApplePayItem(
            type: 'final',
            label: _paymentLabel,
            amount: amount,
          )
        ],
      ),
    );

    await StripePayment.completeNativePayRequest();
}

当我在模拟器上 运行 时,我可以看到付款已完成,并且可以在 Stripe 仪表板上查看请求,不幸的是,付款仍然为 0:

在查看代码之前,请确保您已完成以下步骤: 0. 添加stripe_payment。

  1. 已创建商家 ID。
  2. Apple Pay 已在 Xcode 中启用。
  3. 条带“标准密钥”和“受限密钥”已生成。
    • 标准密钥包含可发布密钥和秘密密钥
    • 在 Flutter 项目中使用可发布的密钥。
    • 限制密钥在服务器端中使用。

我为原生支付做了什么:

  1. 调用 paymentRequestWithNativePay() 获取令牌。
  2. 使用自己实施的收费方法收费(在服务器端,确保您使用受限密钥并且它具有收费写入权限)。
  3. 调用 paymentRequestWithNativePay()
    void handleNativePayment(BuildContext context, String amountInStr) async {
        // I used environment configurations for ANDROID_PAY_MODE, use "test" in test mode
        // and uses "production" in production mode
        StripePayment.setOptions(StripeOptions(
            publishableKey: _publishableKey,
            merchantId: _merchantId,
            androidPayMode: EnvironmentConfig.ANDROID_PAY_MODE,
        ));
    
        // this is my service class talks to server side API 
        PaymentService paymentService = Provider.of<PaymentService>(
          context,
          listen: false,
        );
    
        Token token = await StripePayment.paymentRequestWithNativePay(
          androidPayOptions: AndroidPayPaymentRequest(
            totalPrice: amountInStr,
            currencyCode: _currencyCode,
          ),
          applePayOptions: ApplePayPaymentOptions(
            countryCode: _countryCode,
            currencyCode: _currencyCode,
            items: [
              ApplePayItem(
                type: 'final',
                label: paymentLabel,
                amount: amountInStr,
              )
            ],
          ),
        );
    
        // converts amount from string to int, and it is in cents
        dynamic chargeResult = await paymentService.charge({
          "token": token.tokenId,
          "amount": double.parse(amountInStr) * 100,
          "currency": _currencyCode,
        });
    
        if (chargeResult is ChargeResult) {
          _buildSnackBar(context, "Payment success", Colors.green);
        } else {
          _buildSnackBar(context, "Payment fail", Colors.red);
        }
    
        await StripePayment.completeNativePayRequest();
      }

  _buildSnackBar(BuildContext context, String content, Color color) {
    final snackBar = SnackBar(
      content: Text(content),
      backgroundColor: color,
    );
    Scaffold.of(context).showSnackBar(snackBar);
  }

这是 Flutter 中的 PaymentService。您需要使用 Stripe 受限密钥实施服务器端收费 API 调用。

class PaymentService {
  var logger = Logger(printer: PrettyPrinter());

  Future<dynamic> charge(Map<String, dynamic> data) async {
    Map<String, dynamic> charge = {
      "source": data["token"],
      "amount": data["amount"],
      "currency": data["currency"],
    };
    final response = await DioHttp.post('/stripe/payment/charge', charge);
    if (response.containsKey("results")) {
      return ChargeResult.fromMap(response["results"]);
    } else {
      String errorMessage = response["errors"][0]["description"];
      return errorMessage;
    }
  }
}

还有一件事需要您注意:

用Androidphone测试时,不要用Stripe测试卡号,它总是给你请求失败(错误代码OR-CCSEH-21)。您需要做的是:

  1. 将android支付模式设置为'test'。
  2. 用你的own/real卡支付就可以了(在下面附上的支付记录中,你可以看到最后一笔支付有我的名字,那是因为我用我自己的卡支付androidgoogle支付测试)

希望对有需要的开发者有所帮助。