Appearance
Seller and payout screening
A marketplace screens more than the seller it onboards: payouts can go to an account someone else holds. This pack screens both names through an app, the seller's in a call_app step and the payout account holder's in an app rule, and treats the two hits differently: the seller's rejects, the holder's opens a review. Pack: examples/policies/seller-payout-screening/.
A pattern for screening several parties, not compliance guidance: who must be screened, against which lists, and whether a hit on a third party blocks the seller are the tenant's and the vendor's business. The pack screens with the deterministic mock-sanctions app, which the development tenant has installed with the blocklist Evil Corp; a tenant without that install can import the pack, but its runs fail on unknown_app until the app is installed and enabled.
The decision it automates
Whether a seller can start receiving payouts without a person looking. A seller on the list is rejected outright; a clean seller whose payouts go to a listed account holder is held for a reviewer, who decides whether the account changes or the seller goes.
Data expected
- A subject of kind
sellerwithdata.nameanddata.country, anddata.payoutAccountHolder: the name on the account payouts go to, which the integrating system sets to the seller's own name when the seller holds the account. - No collection flow: the marketplace already holds both names.
Steps and rules
| Step | Type | Why |
|---|---|---|
screen_seller | call_app | mock-sanctions screen on subject.name and subject.country; output under sellerScreening (hit, matches), recorded with the run. |
rules | evaluate_rules | The two rules below, under the default policy: a failed block rule rejects, a failed warn rule sends the run to review. |
route | branch | rules.outcome == manual_review opens the review case; an approval or a rejection goes straight to the decision. |
payout_review | create_case | payout_review, priority high, 24-hour SLA. |
decide | emit_decision | The reviewer's decision when there was a case, otherwise from the rules: a seller hit rejects whatever the holder's screen said. |
| Rule | Type | Severity, weight | Fails when |
|---|---|---|---|
payout_seller_sanctions_hit | comparison | block, 100 | sellerScreening.hit == true: reads the step's output, so the vendor is called once however many rules read it |
payout_holder_sanctions_hit | app | warn, 50 | mock-sanctions screen on subject.payoutAccountHolder returns hit: true |
The two rules show the trade-off between the two ways of calling a vendor. A step records its output in the run context, where every later rule reads it and where a backtest finds it again in the recorded evaluation. An app rule calls the vendor while the rules are evaluated: it needs no step and no output key, but a dry run or a backtest cannot call the vendor, so the rule comes back skipped there. Screen with a step whatever the rules must be able to replay.
What a reviewer sees
A payout_review case with the two rule results: the seller's screen passed, the holder's failed, with the matched names the app returned in the failed rule's details. A case queue in the admin console can pin the type (see Admin console: queues and filters).
How to adapt it
Install the opensanctions app from the catalogue (it needs its apiKey secret) and name it in the step and in the rule instead of mock-sanctions: the screen action takes the same name and country, plus type (Company by default; set input: { "type": "Person" } on the rule when the account holders are people). Screen the seller's directors or beneficial owners the same way, one app rule per party, or collect them in a flow and call screenBatch from one step.
Run it
bash
pnpm policy:import examples/policies/seller-payout-screening --publishThe fixture (expect.json) onboards Northwind Traders with payouts to Evil Corp: the seller's screen is clean, the holder's rule fails, the run opens a payout_review case, the check rejects it and the run completes with a manual reject; sellerScreening.hit is false in the run context.