Guides
Delivery proof guide
End-to-end walkthrough for food delivery, e-commerce, and last-mile logistics businesses.
The problem this solves
When a customer claims their order never arrived, you have no evidence either way. The rider says they delivered. The customer says they did not. Without timestamped GPS proof at the moment of delivery, you always lose the dispute.
SwiftProof gives you a tamper-proof record of every step — packing, collection, and delivery — with GPS coordinates, exact timestamps, and a cryptographic signature that cannot be faked after the fact.
Integration pattern
Create a chain when the order is confirmed. Send the confirmation links immediately so actors receive them before they need them.
order-confirmed.js
// Called when order is placed and kitchen is assigned async function onOrderConfirmed(order) { const chain = await sp.chains.create({ title: `Order #\${order.id} — \${order.deliveryAddress}`, metadata: { orderId: order.id, customerId: order.customerId }, actors: [ { event: 'packed', actor: `Kitchen — \${order.kitchen.name}` }, { event: 'collected', actor: `Rider — \${order.rider.name}` }, { event: 'delivered', actor: `Rider — \${order.rider.name}` }, ], }); // Save chain ID against the order await db.orders.update(order.id, { swiftproofChainId: chain.chain_id }); // Distribute links await sendWhatsApp(order.kitchen.phone, `Confirm packing for order #\${order.id}: \${chain.handoffs[0].confirmation_url}`); await sendWhatsApp(order.rider.phone, `Collect & deliver order #\${order.id}. Links: \${chain.handoffs[1].confirmation_url}`); await sendSMS(order.customer.phone, `Track your order: \${chain.tracking_url}`); }
Handling disputes
When a customer raises a dispute, verify the chain and use the audit trail as evidence.
dispute-handler.js
async function resolveDispute(orderId) { const order = await db.orders.find(orderId); const proof = await sp.chains.verify(order.swiftproofChainId); if (!proof.verified) { // Chain incomplete — delivery not confirmed. Honour refund. return { decision: 'refund', reason: 'delivery not confirmed' }; } const delivery = proof.trail.find(s => s.event === 'delivered'); // delivery.location, delivery.confirmed_at, delivery.coordinates // all tamper-proof and admissible as evidence return { decision: 'reject', evidence: { location: delivery.location, time: delivery.confirmed_at } }; }
GPS at delivery beats customer claims. The confirmation page captures coordinates at the exact moment the rider taps confirm. The timestamp comes from the server, not the rider's device, so it cannot be manipulated.
Edge cases
- Rider changes mid-delivery — create a new chain with the replacement rider. Link both chain IDs to the order.
- Kitchen is busy and packs late — the confirmation link stays valid until it expires. No action needed.
- Link expires before rider confirms — use handoffs.resend() to issue a fresh link. The resend is logged automatically.