PAYATHON 2026

React Native 集成 Cashfree 时提示 orderAmount is required

支付老李

结论

参数对象中虽然有 orderAmount,但传入的 150 是 JavaScript 数字。这个版本的 Cashfree React Native SDK 通过原生桥接读取支付参数时,通常要求参数值为字符串。数字可能无法正确解析,并被视为“未提供”,因此返回:

{"type":"CashFreeResponse","txMsg":"orderAmount not provided","txStatus":"FAILED"}

将金额改成字符串 "150"。调用 startPaymentWEB 前,最好也把其他支付参数统一转换为字符串。

正确写法

const handlePayment = response => {
  const mode = 'TEST';

  const paymentParams = {
    appId: String(response.credentials.app_id),
    orderId: String(response.credentials.order_id),
    orderCurrency: 'INR',
    orderAmount: '150',
    customerPhone: String(response.user.mobile),
    customerEmail: String(response.user.email),
    tokenData: String(response.payment_info.cftoken),
    orderNote: 'Subscription Payment',
    customerName: String(response.user.name),
  };

  console.log('paymentParams', paymentParams);

  RNPgReactNativeSDK.startPaymentWEB(
    paymentParams,
    mode,
    result => {
      console.log('Cashfree result', result);

      try {
        const parsedResult = JSON.parse(result);
        console.log('Parsed result', parsedResult);
      } catch (error) {
        console.error('Unable to parse Cashfree result', error);
      }
    }
  );
};

如果金额来自接口或计算结果,请显式转换:

const amount = String(response.data.price);

如果需要保留两位小数,可以这样处理:

const amount = Number(response.data.price).toFixed(2);

然后传入:

orderAmount: amount

为什么数字 150 会被识别为缺失

React Native 调用 Android 原生模块时,会通过桥接层传递 JavaScript 对象。旧版或某些特定版本的 Cashfree SDK 可能会按字符串类型读取参数,例如在原生端使用类似字符串取值的方法。

因此:

orderAmount: 150

与:

orderAmount: '150'

并不等价。前者是 number,后者是 string。如果 SDK 没有兼容数字类型,就可能读到空值,随后报错 orderAmount not provided。

调用前可以检查实际类型:

console.log(paymentParams.orderAmount);
console.log(typeof paymentParams.orderAmount);

预期输出为:

150
string

还需要检查的参数

除了参数类型,还应确认以下内容:

  • orderAmount 必须大于 0,并符合 Cashfree 接受的金额格式。
  • orderId、orderAmount 和 orderCurrency 必须与服务端生成支付 token 时使用的值一致。
  • tokenData 应由服务端提供,不要在 React Native 客户端使用 Cashfree 密钥自行生成。
  • TEST 模式必须使用测试环境的 appId 和 token,不能混用生产环境凭据。
  • 不要传入 undefined、null 或对象类型,尤其要检查手机号、邮箱、订单号和 token。
  • 如果没有配置 notifyUrl,不要传空字符串,直接省略通常更稳妥。是否必填应以当前 SDK 版本的文档为准。

调用前可以统一过滤并转换参数:

const paymentParams = {
  appId: response.credentials.app_id,
  orderId: response.credentials.order_id,
  orderCurrency: 'INR',
  orderAmount: response.data.price,
  customerPhone: response.user.mobile,
  customerEmail: response.user.email,
  tokenData: response.payment_info.cftoken,
  orderNote: 'Subscription Payment',
  customerName: response.user.name,
};

const normalizedParams = Object.fromEntries(
  Object.entries(paymentParams)
    .filter(([, value]) => value !== undefined && value !== null && value !== '')
    .map(([key, value]) => [key, String(value)])
);

RNPgReactNativeSDK.startPaymentWEB(
  normalizedParams,
  'TEST',
  result => {
    console.log(result);
  }
);

需要修改的主要内容是:

orderAmount: '150'

如果改成字符串后仍然失败,请核对服务端生成 cftoken 时提交的订单号、金额和币种,确认它们与客户端传给 startPaymentWEB 的值完全一致。

备注:内容仅供参考。