#1102 — Implement Docuseal webhooks and handle Merchant status

Repo: Twill-AI/facade State: closed | Status: done Assignee: meliascosta, sparsh-twillpayments

Created: 2026-03-05 · Updated: 2026-03-19

Description

Context

When a merchant completes signing in Docuseal, Docuseal fires a submitter.completed webhook. The backend must receive this, validate it, update the merchant record, and trigger submission to the selected processor.

Webhook handler

POST /docuseal/webhook

Docuseal fires submitter.completed when signing is done. Payload includes the submission ID and submitter email.

Handler behavior:

  1. Validate Docuseal webhook signature (confirm auth method with #1098 setup)
  2. Look up merchant by docuseal_submission_id (set in #1099)
  3. Confirm availability of all required fields, otherwise through a descriptive error
  4. Set signed_at = now() on merchant
  5. Update merchant status → UNDERWRITING
  6. Call the appropriate processor submission function from processor_fee_mapping.py (added in #1096) based on merchant.processor: - luqrato_luqra_fee_schedule() → submit to Luqra API
    • emsto_ems_fee_schedule() → submit to EMS API
  7. Log activity: “Merchant agreement signed. Application submitted to {processor}.”
  8. Return 200

AC

  • Webhook endpoint created and signature validation in place
  • Merchant looked up by docuseal_submission_id
  • signed_at set on completion
  • Merchant status transitions to SENT_FOR_SIGNATURE
  • Processor submission triggered via mapping layer from #1096
  • Activity logged
  • Create get endpoint that returns json sent to luqra
  • Create post endpoint which takes json as input an

Notes

Add implementation notes, blockers, and context here

Add wikilinks to related people, meetings, or other tickets