Testing different delivery methods. Same pass bytes each time — only the HTTP delivery path differs.
Test A/B — Direct download to test locally on Mac
Generates pass and downloads as demo.pkpass to Downloads folder.
Test C — Uploaded public storage URL (ends in .pkpass)
Generates pass → uploads to Base44 public storage → direct file URL. Storage likely serves application/octet-stream not application/vnd.apple.pkpass — expected to fail.
Test D — Cloudflare Worker proxy at wallet.playoneweknow.co.uk/pass/demo.pkpass
This is the most reliable Safari delivery method. The Worker re-serves the pass bytes from a clean .pkpass path with forced Content-Type: application/vnd.apple.pkpass.
✅ This is the fix for Safari. Deploy the Cloudflare Worker below, then tap on iPhone Safari.
+ Add to Wallet (D) — Recommended ✓Cloudflare Worker code for Test D
1. Go to Cloudflare Dashboard → Workers & Pages → Create Worker
2. Paste the code below
3. Add a custom domain route: wallet.playoneweknow.co.uk/*
4. Deploy — then tap Test D on iPhone Safari
// Cloudflare Worker — deploy at wallet.playoneweknow.co.uk
// Routes: GET /pass/*.pkpass → fetches from Base44 generateApplePass and re-serves
// with forced Content-Type: application/vnd.apple.pkpass
const PASS_FUNCTION_URL = "https://playoneweknow.co.uk/functions/generateApplePass";
const DEMO_QR = "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=https://app.yuubee.com/pay/demo";
export default {
async fetch(request) {
const url = new URL(request.url);
if (!url.pathname.endsWith(".pkpass")) {
return new Response("Not found", { status: 404 });
}
// Forward query params if present, or use demo defaults
const params = new URLSearchParams({
qrCodeUrl: url.searchParams.get("qrCodeUrl") || DEMO_QR,
displayName: url.searchParams.get("displayName") || "POWK User",
userId: url.searchParams.get("userId") || "user",
});
const upstream = await fetch(`${PASS_FUNCTION_URL}?${params}`);
if (!upstream.ok) {
return new Response("Upstream error: " + upstream.status, { status: 502 });
}
const body = await upstream.arrayBuffer();
return new Response(body, {
status: 200,
headers: {
"Content-Type": "application/vnd.apple.pkpass",
"Content-Disposition": 'inline; filename="pass.pkpass"',
"Content-Length": body.byteLength.toString(),
"Cache-Control": "no-store",
},
});
},
};We use cookies to understand how you use POWK and improve your experience. By continuing to browse, you agree to our use of cookies.