One pass, one language at a time
One wallet pass can serve Arabic and English readers, but not by printing both languages on the same card. What changes between the two is the label set, the digit shapes, the text alignment, and the direction your artwork reads in. The values you type stay exactly as you typed them: a reward called "Free flat white" is not translated by the wallet.
Both Apple Wallet and Google Wallet localize labels, not content. On Apple's side a pass is a signed bundle, and any string you want translated goes in a per-language file inside it, at lang.lproj/pass.strings; the values in pass.json act as lookup keys. Google Wallet inverts the shape: each localizable field carries a defaultValue plus a list of translatedValues tagged with language codes, and the wallet app picks the one matching the device.
Waya resolves the language once, when the pass is minted. Every card has a Pass language setting with three options: English, Arabic, or Auto, and Auto reads the enrolling browser's Accept-Language header, defaulting to English. Labels then come from one bilingual registry shared by both platforms, so SHOP, NAME, REWARD, BALANCE, STAMPS, POINTS, and Terms & Conditions render with an Arabic counterpart on an Arabic card and never drift between Apple and Google.
The honest cost of that choice: because the language is baked in at mint time, a customer who switches their phone from Arabic to English keeps the Arabic labels until the pass is reissued. None of this touches your till either. Waya has no POS integration, so every value on the pass comes from the card record and from staff scans.
Alignment is absolute, and images never mirror
PassKit field alignment is absolute, not logical. The four constants are PKTextAlignmentLeft, PKTextAlignmentCenter, PKTextAlignmentRight, and PKTextAlignmentNatural, and "left" means left on an Arabic pass too. Hardcode the holder name left and the reward right, and that pair does not swap when the labels turn into Arabic. PKTextAlignmentNatural aligns by the reading direction of the text itself, which is usually what you want for a person's name.
Images never mirror. Wallet chrome may lay itself out right-to-left based on the device language, but a PNG is a PNG. Waya renders the stamp strip server-side, so on Arabic cards we reverse the fill order deliberately: the first stamp earned appears on the right and progress moves leftward toward the reward. Anything you draw, you mirror on purpose: arrows, progress bars, a row of ten slots, any logo with a directional flourish.
Digits and dates: two silent switches
Waya's rule across the product is Latin digits, 0 through 9, even on Arabic cards and in Arabic interface copy. Saudi readers read Latin digits fluently, and a counter written that way stays consistent with the price on the receipt and the amount on the payment terminal. Arabic-Indic digit shapes, the block at U+0660 to U+0669, also cost you glanceability in a field a cashier reads in under a second.
The trap is that one locale API call can take both decisions away from you. Calling toLocaleDateString with the locale ar-SA returns an Umm al-Qura Hijri date in Arabic-Indic digits on most JavaScript runtimes, so a card set to expire on 31 December 2026 quietly displays a different year. Pin the calendar and numbering system in the tag instead: ar-SA-u-ca-gregory-nu-latn gives you a Gregorian date in Latin digits.
Money deserves the same care. Write store credit as "SAR 45.00" with fixed two decimals rather than running the number through a locale currency formatter, so the string is identical on the Arabic and English variants of the same card. Hijri dates are worth supporting on input, where a customer genuinely thinks in them: our enrollment form accepts a Hijri birthday and stores the Gregorian equivalent.
Bidi: why the plus sign jumps to the wrong end
An Arabic pass puts your values inside a right-to-left paragraph, and the Unicode Bidirectional Algorithm decides where neutral characters land. Punctuation, spaces, plus signs, and brackets carry no direction of their own, so they take one from their neighbors. Nothing is corrupted when this bites; the stored bytes are fine and the display is following the spec exactly.
The classic symptom is a phone number. Stored as "+966 55 123 4567" and dropped into a right-to-left back field, it renders with the plus sign at the right-hand end of the number. Prefix the run with U+200E, the left-to-right mark, or wrap it in the U+2066 and U+2069 isolate pair, and it renders in the order you meant. A stamp count like "3/10" is safe, because the digits are typed as European numbers and a separator between two of them inherits their direction.
One encoding detail belongs here too. Apple's barcode dictionary carries a messageEncoding, and ISO-8859-1 is the value most pass generators use, ours included, because scanners handle it reliably. It cannot represent Arabic characters at all, so keep the barcode payload ASCII: Waya puts the pass serial in it, never a name or a shop label.
Names: one field beats parsing
Arabic names do not split into first and last. A full name can run given name, father's name, grandfather's name, and a family or tribal name: four tokens where a Western form expects two. Split on whitespace, call the last token a surname, and you print something the customer does not recognize as their own name.
So the enrollment form asks for one name and a mobile number, and that is the whole form. Scan the shop's QR code, type two things, tap once to add the card to Apple Wallet or Google Wallet. No account, no password, no app to download, and no name parsing to get wrong in either language.
Handle the empty case by removing the field, not blanking it. Waya's stamp layout omits the NAME field entirely when a customer has no name set, so the row reads as just the reward instead of a blank value beside a label. Test the extremes too: a two-character name and a twenty-eight-character one, in each language.
Truncation is a width problem, not a character count
There is no published character limit for a wallet field value. What you have is a fixed pixel width per field; the wallet shrinks the text a step, then truncates with an ellipsis. Arabic is often shorter in character count than the same English phrase and no shorter on screen, and because the script is connected, a cut mid-word breaks the letterforms and reads worse than a clipped English word.
Budget by field. Measured on our own cards on a 390pt-wide iPhone, a header value holds up at roughly 8 to 10 characters, an auxiliary label at about 14, and a primary value at about 20 before it starts shrinking. Those are working numbers from our passes, not a documented spec, so check yours against the longest real value you have.
The fix is editorial rather than technical: short token on the front, full wording on the back. Put "Free coffee" in the reward field and "One free 12 oz coffee after 10 paid drinks, dine-in only" in a back field, where text wraps and has room. Watch the shop name as well, since it also appears as the sender on wallet update notifications, where space is tighter than on the pass.
Test on a device set to each language
Change the device language, not the website's. The wallet renders a pass with the strings and layout direction the operating system hands it, so flipping a language toggle in your dashboard proves nothing about the card. On iOS, open Settings, then General, then Language & Region, and set iPhone Language to Arabic. On Android, open Settings, then System, then Languages, move Arabic to the top, and reopen Google Wallet.
If you have only one phone, the iOS Simulator covers the Apple side. Set the simulated device's language first, then drag a .pkpass file onto the Simulator window and it opens in Wallet. Screenshot each variant and put the two images side by side, because drift shows up in a pair of screenshots that you will never notice in one.
Look for six things in each screenshot: which script the labels use, the digit shapes on every number, whether alignment follows the reading direction, whether any value has been cut with an ellipsis, whether the stamp strip fills from the correct side, and whether the back-of-pass links still open. Then send yourself one wallet message in each language and read it on the lock screen, which gives you less room than the pass does. These are wallet push notifications, not SMS, so the budget is the notification's.
The free plan covers this test end to end: 0 SAR, up to 100 customers, 100 wallet messages a month, one card, one branch, no credit card. Mint a real pass to your own phone, switch the phone's language, mint a second one. If you decide two audiences deserve two separate cards rather than one compromise, that starts on Growth at 85 SAR a month, which allows up to 10 cards.
Frequently asked questions
Can one wallet pass show both Arabic and English at the same time?
No, a pass renders one label set at a time, and stacking two languages into one field wastes the little width a wallet gives you. Apple resolves strings from a per-language pass.strings file in the bundle, and Google Wallet picks the matching entry from translatedValues, so each device sees a single language. If you genuinely serve two audiences, issue two cards rather than one crowded card.
Does the customer's phone language change the pass automatically?
Only if the pass ships a translated string table for that language. Waya resolves the language when the pass is minted, either from the card's Pass language setting or from the enrolling device when the setting is Auto, so an existing pass keeps the labels it was issued with. Switching a phone from Arabic to English does not re-translate a card already sitting in the wallet.
Why does my Arabic pass show a date in the wrong year?
Because the locale ar-SA defaults to the Umm al-Qura Hijri calendar in most JavaScript runtimes, so 31 December 2026 formats as a Hijri date in Arabic-Indic digits. Pin both settings in the locale tag: ar-SA-u-ca-gregory-nu-latn returns a Gregorian date in Latin digits. Waya's rule is Latin digits on every card, Arabic or English.
Why does the plus sign on my phone number appear at the wrong end?
The Unicode Bidirectional Algorithm gives neutral characters the direction of their neighbors, so a leading plus sign inside a right-to-left field lands visually at the right end of the number. The stored data is intact; only the display order changed. Prefix the number with U+200E, or wrap it in U+2066 and U+2069, and it renders left-to-right inside the Arabic field.
How do I test an Arabic wallet pass without an Arabic phone?
Set your own phone's system language to Arabic for ten minutes, or drag the .pkpass file onto an iOS Simulator whose language you have already switched. Both show you the real rendering: label script, alignment, digit shapes, and truncation. Screenshot each language and compare the two images side by side.