Coinbase webhook: Property 'metadata' does not exist on type 'CheckoutResource'

153 Views Asked by At

I want to access the metadata after a payment has succeeded with coinbase by listening to the charge:confirmed event. In the example for a webhook payload (https://docs.cloud.coinbase.com/commerce/docs/webhooks-events) the event.data has a metadata property from which I should be able to retrieve the metadata that is provided when creating the charge.

export const webhook = async (req: Request, res: Response) => {
  try {
    const rawBody = req.rawBody;
    const signature: string = req.headers["x-cc-webhook-signature"] as string;

    const event = Webhook.verifyEventBody(
      rawBody,
      signature,
      process.env.COINBASE_WEBHOOK_KEY
    );
    if (event.type === "charge:confirmed") {
      //TODO
      // make database entry and send nodemailer mail to notify user of purchase
      const metadata = event.data.metadata;
    }

    res.status(201).json({ msg: "Success" });
  } catch (error) {
    console.log(error.message);
    res.status(400).json({ msg: "An error occured" });
  }
};

When trying to access the metadata,

const metadata = event.data.metadata;

I get a typescript error:

Property 'metadata' does not exist on type 'ChargeResource | CheckoutResource'. Property 'metadata' does not exist on type 'CheckoutResource'

How can I get the metadata? I cannot log the event.data since the coinbase API does not provide a way to test their webhooks unless you do real transactions.

1

There are 1 best solutions below

0
Lin Du On BEST ANSWER

Webhook.verifyEventBody() method returns an Event which extends EventResource.

interface Event extends EventResource {}

interface EventResource<T = ChargeResource | CheckoutResource> {
  //...

  data: T;
}
interface ChargeResource extends BaseCharge {
  //...
  resource: 'charge';
  metadata: KeyVal;
}
interface CheckoutResource extends BaseCheckout {
  //...
  resource: 'checkout';
}

Only the ChargeResource interface has the metadata field. The CheckoutResource interface does not have it.

You should narrow down the type to ChargeResource for event.data by checking event.data.resource.

const event = Webhook.verifyEventBody('rawBody', 'signature', 'sharedSecret');
if (event.data.resource === 'charge' && event.type === 'charge:confirmed') {
  const metadata = event.data.metadata;
}

package versions

@types/coinbase-commerce-node: 1.0.6
coinbase-commerce-node: 1.0.4