import { createTrigger, TriggerStrategy, Property, } from '@activepieces/pieces-framework'; import { stripeCommon } from '../common'; import { StripeWebhookInformation } from '../common/types'; import { stripeAuth } from '../..'; import { httpClient, HttpMethod } from '@activepieces/pieces-common'; import { isEmpty } from '@activepieces/pieces-framework'; type StripeWebhookPayload = { data: { object: { [key: string]: unknown; }; }; }; import { disputeOutputSchema } from '../output-schemas'; export const stripeNewDispute = createTrigger({ auth: stripeAuth, name: 'new_dispute', classification: 'READ', displayName: 'New Dispute', description: 'Fires when a customer disputes a charge.', aiMetadata: { description: 'Fires when a customer disputes a charge in Stripe (the charge.dispute.created event), emitting the dispute including its reason and evidence due date. Optional filters narrow firing to a specific charge ID or payment intent ID. Use to react to chargebacks, such as alerting a team or gathering evidence.', }, props: { charge: Property.ShortText({ displayName: 'Charge ID', description: 'Only disputes for this charge. Empty: all.', placeholder: 'ch_...', required: false, }), payment_intent: Property.ShortText({ displayName: 'Payment Intent ID', description: 'Only disputes for this payment. Empty: all.', placeholder: 'pi_...', required: false, }), }, outputSchema: disputeOutputSchema, sampleData: { id: 'du_1MtJUT2eZvKYlo2CNaw2HvEv', object: 'dispute', amount: 1000, balance_transactions: [], charge: 'ch_1AZtxr2eZvKYlo2CJDX8whov', created: 1680651737, currency: 'usd', evidence_details: { due_by: 1682294399, has_evidence: false, past_due: false, submission_count: 0, }, is_charge_refundable: true, livemode: false, metadata: {}, payment_intent: 'pi_1AZtxr2eZvKYlo2CJDX8whov', reason: 'general', status: 'needs_response', }, type: TriggerStrategy.WEBHOOK, async onEnable(context) { const webhook = await stripeCommon.subscribeWebhook( 'charge.dispute.created', context.webhookUrl, context.auth.secret_text ); await context.store.put('_new_dispute_trigger', { webhookId: webhook.id, }); }, async onDisable(context) { const webhookInfo = await context.store.get( '_new_dispute_trigger' ); if (webhookInfo !== null && webhookInfo !== undefined) { await stripeCommon.unsubscribeWebhook( webhookInfo.webhookId, context.auth.secret_text ); } }, async test(context) { const response = await httpClient.sendRequest<{ data: { id: string }[] }>({ method: HttpMethod.GET, url: 'https://api.stripe.com/v1/disputes', headers: { Authorization: 'Bearer ' + context.auth.secret_text, 'Content-Type': 'application/x-www-form-urlencoded', }, queryParams: { limit: '5', }, }); if (isEmpty(response.body) || isEmpty(response.body.data)) return []; return response.body.data; }, async run(context) { const payloadBody = context.payload.body as StripeWebhookPayload; const disputeObject = payloadBody.data.object; const { charge, payment_intent } = context.propsValue; if (charge && disputeObject['charge'] !== charge) { return []; } if (payment_intent && disputeObject['payment_intent'] !== payment_intent) { return []; } return [disputeObject]; }, });