【问题标题】:Writing unit tests for stripe webhooks stripe-signature为 stripe webhooks stripe-signature 编写单元测试
【发布时间】:2021-03-26 03:16:48
【问题描述】:

我正在尝试为 Stripe webhook 编写单元测试。问题是我也在验证stripe-signature,但它按预期失败了。

有没有办法使用模拟数据将测试中的正确签名传递给 webhook?

这是我正在尝试处理的 webhook 路由的开始

// Retrieve the event by verifying the signature using the raw body and secret.
let event: Stripe.Event;
const signature = headers["stripe-signature"];

try {
  event = stripe.webhooks.constructEvent(
    raw,
    signature,
    context.env.stripeWebhookSecret
  );
} catch (err) {
  throw new ResourceError(RouteErrorCode.STRIPE_WEBHOOK_SIGNATURE_VERIFICATION_FAILD);
}

// Handle event...

而我正在尝试处理的当前测试,我正在使用 Jest:

const postData = { MOCK WEBHOOK EVENT DATA }

const result = await request(app.app)
  .post("/webhook/stripe")
  .set('stripe-signature', 'HOW TO GET THIS SIGNATURE?')
  .send(postData);

【问题讨论】:

    标签: node.js unit-testing stripe-payments


    【解决方案1】:

    在 Nolan 的帮助下,我能够让签名正常工作。如果其他人需要帮助,我就是这样做的:

    import { createHmac } from 'crypto';
    
    const unixtime = Math.floor(new Date().getTime() / 1000);
    
    // Calculate the signature using the UNIX timestamp, postData and webhook secret
    const signature = createHmac('sha256', stripeWebhookSecret)
      .update(`${unixtime}.${JSON.stringify(postData)}`, 'utf8')
      .digest('hex');
    
    // Set the stripe-signature header with the v1 signature
    // v0 can be any value since its not used in the signature calculation
    const result = await request(app.app)
      .post("/webhook/stripe")
      .set('stripe-signature', `t=${unixtime},v1=${signature},v0=ff`)
      .send(postData);
    

    【讨论】:

    • 即使这种方法也可以解决问题,但应该避免,因为我们是手工完成的,应该使用上面的答案。
    【解决方案2】:

    Stripe 现在在其节点库中公开了一个他们推荐用于创建测试签名的函数:

    测试 Webhook 签名

    您可以使用stripe.webhooks.generateTestHeaderString 模拟来自 Stripe 的 webhook 事件:

    const payload = {
      id: 'evt_test_webhook',
      object: 'event',
    };
    
    const payloadString = JSON.stringify(payload, null, 2);
    const secret = 'whsec_test_secret';
    
    const header = stripe.webhooks.generateTestHeaderString({
      payload: payloadString,
      secret,
    });
    
    const event = stripe.webhooks.constructEvent(payloadString, header, secret);
    
    // Do something with mocked signed event
    expect(event.id).to.equal(payload.id);
    
    

    参考:https://github.com/stripe/stripe-node#webhook-signing

    【讨论】:

    • 这是最好的答案,因为它来自官方文档,我们不需要手动构建签名,这会在 Stripe 更改内部构建签名的方式时破坏我们的测试。跨度>
    猜你喜欢
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2017-07-10
    • 2018-03-09
    • 1970-01-01
    • 2014-04-18
    • 2016-06-11
    • 2021-06-02
    相关资源
    最近更新 更多