mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
fix(native): Android offers TREK Cloud while orders are closed and says a refused purchase is refunded
The licence testers of the internal test buy from a release build, so the plan screen no longer hides the purchase on Android before the opening. Their purchases are Play test purchases, which the cloud serves. A real purchase made before the opening is refused with ordering-closed and never acknowledged, so Google Play refunds it after three days; the claim and the restore now say that instead of a general error. The app still acknowledges a purchase only after a redeem that returned an instance. iOS is unchanged.
This commit is contained in:
@@ -5,6 +5,7 @@ import { StatusBar, Style } from '@capacitor/status-bar';
|
||||
import logoUrl from '../public/icons/icon-white.svg';
|
||||
import logoBlack from '../public/logo-dark.svg'; // #000 wordmark, for light backgrounds
|
||||
import logoWhite from '../public/logo-light.svg'; // #fff wordmark, for dark backgrounds
|
||||
import { opensSoon, refundedBeforeOpening } from '../src/native/cloudOrders';
|
||||
import { fakeIapClient, getIapClient, productIdFor, type Purchase } from '../src/native/iap';
|
||||
import { CLOUD_TERMS_URL, CLOUD_URL, PRIVACY_URL, SERVER_DOCS_URL, STORE_TERMS_URL } from '../src/native/links';
|
||||
import { probeDemo, probeServer, type ProbeFailure, type ProbeGet } from '../src/native/serverAddress';
|
||||
@@ -429,12 +430,14 @@ function offerFor(offer: Offer, plan: CloudPlan, interval: 'month' | 'year'): {
|
||||
|
||||
async function loadOffer(list: CloudPlans): Promise<Offer> {
|
||||
const available = await iapReady;
|
||||
// Closed: a store purchase would be refused at the cloud, so only a test build may buy.
|
||||
const opensSoon = available && list.closed && !(await iap.isSandbox().catch(() => false));
|
||||
const canBuy = available && !opensSoon;
|
||||
if (!canBuy || iap === fakeIapClient) return { canBuy, storePrices: null, opensSoon };
|
||||
// Closed: a real purchase is refused at the cloud, so only a test build may buy on iOS;
|
||||
// Android keeps the button for the licence testers (see cloudOrders.ts).
|
||||
const sandbox = list.closed && !onPlay ? await iap.isSandbox().catch(() => false) : false;
|
||||
const soon = opensSoon({ available, closed: list.closed, sandbox, onPlay });
|
||||
const canBuy = available && !soon;
|
||||
if (!canBuy || iap === fakeIapClient) return { canBuy, storePrices: null, opensSoon: soon };
|
||||
const ids = list.plans.flatMap((p) => [productIdFor(p.id, 'month'), productIdFor(p.id, 'year')]);
|
||||
return { canBuy, storePrices: await iap.prices(ids), opensSoon };
|
||||
return { canBuy, storePrices: await iap.prices(ids), opensSoon: soon };
|
||||
}
|
||||
|
||||
function planCard(plan: CloudPlan, interval: 'month' | 'year', offer: Offer): HTMLElement {
|
||||
@@ -526,7 +529,10 @@ function planFooter(offer: Offer, plans: CloudPlan[]): Node[] {
|
||||
void notify(NotificationType.Error);
|
||||
restore.disabled = false;
|
||||
status.className = 'hint bad';
|
||||
status.textContent = t('native.plans.restoreFailed');
|
||||
// Bought before the opening: refused, unacknowledged, and refunded by Google Play.
|
||||
status.textContent = refundedBeforeOpening(redeemed.code, onPlay)
|
||||
? t('native.claim.closedRefund')
|
||||
: t('native.plans.restoreFailed');
|
||||
});
|
||||
|
||||
// A payment that was pending (cash, some carrier billing) and has cleared since:
|
||||
@@ -838,7 +844,9 @@ function showClaim(
|
||||
slugNote.textContent = t('native.claim.taken');
|
||||
slugNote.className = 'hint bad';
|
||||
} else {
|
||||
error.textContent = t('native.claim.redeemFailed');
|
||||
error.textContent = refundedBeforeOpening(redeemed.code, onPlay)
|
||||
? t('native.claim.closedRefund')
|
||||
: t('native.claim.redeemFailed');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { opensSoon, refundedBeforeOpening } from './cloudOrders';
|
||||
|
||||
describe('opensSoon', () => {
|
||||
const base = { available: true, closed: true, sandbox: false, onPlay: false };
|
||||
|
||||
it('FE-NATIVE-ORDERS-001: closed orders hide the purchase from an App Store build', () => {
|
||||
expect(opensSoon(base)).toBe(true);
|
||||
});
|
||||
|
||||
it('FE-NATIVE-ORDERS-002: a TestFlight build may buy while orders are closed', () => {
|
||||
expect(opensSoon({ ...base, sandbox: true })).toBe(false);
|
||||
});
|
||||
|
||||
it('FE-NATIVE-ORDERS-003: an Android release build keeps the purchase while orders are closed', () => {
|
||||
expect(opensSoon({ ...base, onPlay: true })).toBe(false);
|
||||
});
|
||||
|
||||
it('FE-NATIVE-ORDERS-004: open orders and a binary without a store never say "opens soon"', () => {
|
||||
expect(opensSoon({ ...base, closed: false })).toBe(false);
|
||||
expect(opensSoon({ ...base, available: false })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('refundedBeforeOpening', () => {
|
||||
it('FE-NATIVE-ORDERS-005: a purchase refused as ordering-closed on Android is the refunded one', () => {
|
||||
expect(refundedBeforeOpening('ordering-closed', true)).toBe(true);
|
||||
});
|
||||
|
||||
it('FE-NATIVE-ORDERS-006: other refusals, and ordering-closed on iOS, keep the general message', () => {
|
||||
expect(refundedBeforeOpening('ordering-closed', false)).toBe(false);
|
||||
expect(refundedBeforeOpening('redeem-failed', true)).toBe(false);
|
||||
expect(refundedBeforeOpening(undefined, true)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* What the app's plan screens do while TREK Cloud's orders are closed, apart
|
||||
* from the screens themselves so it can be tested.
|
||||
*
|
||||
* On iOS only a test build (TestFlight, App Review) may buy then: the App Store
|
||||
* charges it nothing and the cloud serves it. On Android the button shows in
|
||||
* every build, so the licence testers of the internal test can buy from a
|
||||
* release build; their purchases are Play test purchases, which the cloud
|
||||
* serves. A real purchase made before the opening is refused at the cloud with
|
||||
* `ordering-closed` and never acknowledged, so Google Play refunds it after
|
||||
* three days, and the app says so instead of showing a general error.
|
||||
*/
|
||||
|
||||
/** Whether the plans show without a way to buy: orders are closed and this build may not buy before the opening. */
|
||||
export function opensSoon(opts: { available: boolean; closed: boolean; sandbox: boolean; onPlay: boolean }): boolean {
|
||||
return opts.available && opts.closed && !opts.sandbox && !opts.onPlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the cloud refused a purchase because it came before the opening, on
|
||||
* Android, where Google Play then refunds it: the app says so rather than
|
||||
* showing a general error. On iOS no real purchase gets this far.
|
||||
*/
|
||||
export function refundedBeforeOpening(code: string | undefined, onPlay: boolean): boolean {
|
||||
return onPlay && code === 'ordering-closed';
|
||||
}
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'تم إلغاء الشراء.',
|
||||
'native.claim.failed': 'لم تتم عملية الشراء. حاول مرة أخرى.',
|
||||
'native.claim.redeemFailed': 'تعذّر علينا إعداد TREK الخاص بك. حاول مرة أخرى.',
|
||||
'native.claim.closedRefund': 'يفتح TREK Cloud قريبًا. سيرد Google Play ثمن هذا الشراء تلقائيًا خلال ثلاثة أيام.',
|
||||
'native.plans.restore': 'استعادة المشتريات',
|
||||
'native.plans.restoring': 'جارٍ التحقق من مشترياتك…',
|
||||
'native.plans.restoreNone': 'لم يُعثر على اشتراك نشط لمعرّف Apple هذا.',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Alış ləğv edildi.',
|
||||
'native.claim.failed': 'Alış baş tutmadı. Zəhmət olmasa yenidən cəhd edin.',
|
||||
'native.claim.redeemFailed': 'TREK-inizi hazırlaya bilmədik. Zəhmət olmasa yenidən cəhd edin.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud tezliklə açılır. Google Play bu alışın pulunu üç gün ərzində avtomatik qaytarır.',
|
||||
'native.plans.restore': 'Alışları bərpa et',
|
||||
'native.plans.restoring': 'Alışlarınız yoxlanılır…',
|
||||
'native.plans.restoreNone': 'Bu Apple ID üçün aktiv abunə tapılmadı.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Compra cancelada.',
|
||||
'native.claim.failed': 'A compra não foi concluída. Tente novamente.',
|
||||
'native.claim.redeemFailed': 'Não conseguimos preparar seu TREK. Tente novamente.',
|
||||
'native.claim.closedRefund':
|
||||
'O TREK Cloud abre em breve. O Google Play reembolsa esta compra automaticamente em até três dias.',
|
||||
'native.plans.restore': 'Restaurar compras',
|
||||
'native.plans.restoring': 'Verificando suas compras…',
|
||||
'native.plans.restoreNone': 'Nenhuma assinatura ativa encontrada neste ID Apple.',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Compra cancel·lada.',
|
||||
'native.claim.failed': 'La compra no s’ha completat. Torna-ho a provar.',
|
||||
'native.claim.redeemFailed': 'No hem pogut preparar el teu TREK. Torna-ho a provar.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud obre aviat. Google Play et reemborsa aquesta compra automàticament en un termini de tres dies.',
|
||||
'native.plans.restore': 'Restaura les compres',
|
||||
'native.plans.restoring': 'Comprovant les teves compres…',
|
||||
'native.plans.restoreNone': 'No s’ha trobat cap subscripció activa en aquest ID d’Apple.',
|
||||
|
||||
@@ -68,6 +68,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Nákup zrušen.',
|
||||
'native.claim.failed': 'Nákup se nezdařil. Zkuste to znovu.',
|
||||
'native.claim.redeemFailed': 'Nepodařilo se připravit váš TREK. Zkuste to znovu.',
|
||||
'native.claim.closedRefund': 'TREK Cloud brzy otevírá. Google Play vám tento nákup automaticky vrátí do tří dnů.',
|
||||
'native.plans.restore': 'Obnovit nákupy',
|
||||
'native.plans.restoring': 'Kontrolujeme vaše nákupy…',
|
||||
'native.plans.restoreNone': 'Pro toto Apple ID nebylo nalezeno žádné aktivní předplatné.',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Kauf abgebrochen.',
|
||||
'native.claim.failed': 'Der Kauf hat nicht geklappt. Bitte versuch es erneut.',
|
||||
'native.claim.redeemFailed': 'Wir konnten deine TREK nicht einrichten. Bitte versuch es erneut.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud startet bald. Google Play erstattet dir diesen Kauf automatisch innerhalb von drei Tagen.',
|
||||
'native.plans.restore': 'Käufe wiederherstellen',
|
||||
'native.plans.restoring': 'Deine Käufe werden geprüft…',
|
||||
'native.plans.restoreNone': 'Für diese Apple-ID wurde kein aktives Abo gefunden.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Purchase cancelled.',
|
||||
'native.claim.failed': 'The purchase did not go through. Please try again.',
|
||||
'native.claim.redeemFailed': 'We could not set up your TREK. Please try again.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud opens soon. Google Play refunds this purchase automatically within three days.',
|
||||
'native.plans.restore': 'Restore purchases',
|
||||
'native.plans.restoring': 'Checking your purchases…',
|
||||
'native.plans.restoreNone': 'No active subscription found on this Apple ID.',
|
||||
|
||||
@@ -70,6 +70,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Compra cancelada.',
|
||||
'native.claim.failed': 'La compra no se completó. Inténtalo de nuevo.',
|
||||
'native.claim.redeemFailed': 'No pudimos preparar tu TREK. Inténtalo de nuevo.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud abre pronto. Google Play te reembolsa esta compra automáticamente en un plazo de tres días.',
|
||||
'native.plans.restore': 'Restaurar compras',
|
||||
'native.plans.restoring': 'Comprobando tus compras…',
|
||||
'native.plans.restoreNone': 'No se encontró ninguna suscripción activa en este ID de Apple.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Ost tühistatud.',
|
||||
'native.claim.failed': 'Ost ei õnnestunud. Proovi uuesti.',
|
||||
'native.claim.redeemFailed': 'Me ei saanud sinu TREK-i seadistada. Proovi uuesti.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud avatakse peagi. Google Play maksab selle ostu raha kolme päeva jooksul automaatselt tagasi.',
|
||||
'native.plans.restore': 'Taasta ostud',
|
||||
'native.plans.restoring': 'Kontrollime sinu oste…',
|
||||
'native.plans.restoreNone': 'Selle Apple ID jaoks ei leitud aktiivset tellimust.',
|
||||
|
||||
@@ -70,6 +70,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Achat annulé.',
|
||||
'native.claim.failed': 'L’achat n’a pas abouti. Réessayez.',
|
||||
'native.claim.redeemFailed': 'Nous n’avons pas pu préparer votre TREK. Réessayez.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud ouvre bientôt. Google Play vous rembourse cet achat automatiquement sous trois jours.',
|
||||
'native.plans.restore': 'Restaurer les achats',
|
||||
'native.plans.restoring': 'Vérification de vos achats…',
|
||||
'native.plans.restoreNone': 'Aucun abonnement actif trouvé pour cet identifiant Apple.',
|
||||
|
||||
@@ -71,6 +71,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Η αγορά ακυρώθηκε.',
|
||||
'native.claim.failed': 'Η αγορά δεν ολοκληρώθηκε. Δοκιμάστε ξανά.',
|
||||
'native.claim.redeemFailed': 'Δεν μπορέσαμε να ετοιμάσουμε το TREK σας. Δοκιμάστε ξανά.',
|
||||
'native.claim.closedRefund':
|
||||
'Το TREK Cloud ανοίγει σύντομα. Το Google Play σας επιστρέφει αυτόματα τα χρήματα αυτής της αγοράς μέσα σε τρεις ημέρες.',
|
||||
'native.plans.restore': 'Επαναφορά αγορών',
|
||||
'native.plans.restoring': 'Έλεγχος των αγορών σας…',
|
||||
'native.plans.restoreNone': 'Δεν βρέθηκε ενεργή συνδρομή για αυτό το Apple ID.',
|
||||
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'הרכישה בוטלה.',
|
||||
'native.claim.failed': 'הרכישה לא הושלמה. אנא נסו שוב.',
|
||||
'native.claim.redeemFailed': 'לא הצלחנו להכין את ה-TREK שלכם. אנא נסו שוב.',
|
||||
'native.claim.closedRefund': 'TREK Cloud ייפתח בקרוב. Google Play יחזיר לכם את הרכישה הזו אוטומטית תוך שלושה ימים.',
|
||||
'native.plans.restore': 'שחזור רכישות',
|
||||
'native.plans.restoring': 'בודקים את הרכישות שלך…',
|
||||
'native.plans.restoreNone': 'לא נמצא מינוי פעיל עבור Apple ID זה.',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Vásárlás megszakítva.',
|
||||
'native.claim.failed': 'A vásárlás nem sikerült. Próbáld újra.',
|
||||
'native.claim.redeemFailed': 'Nem sikerült beállítani a TREK-edet. Próbáld újra.',
|
||||
'native.claim.closedRefund':
|
||||
'A TREK Cloud hamarosan nyit. A Google Play három napon belül automatikusan visszatéríti ezt a vásárlást.',
|
||||
'native.plans.restore': 'Vásárlások visszaállítása',
|
||||
'native.plans.restoring': 'Vásárlásaid ellenőrzése…',
|
||||
'native.plans.restoreNone': 'Ehhez az Apple ID-hoz nem található aktív előfizetés.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Pembelian dibatalkan.',
|
||||
'native.claim.failed': 'Pembelian tidak berhasil. Silakan coba lagi.',
|
||||
'native.claim.redeemFailed': 'Kami tidak dapat menyiapkan TREK Anda. Silakan coba lagi.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud segera dibuka. Google Play mengembalikan dana pembelian ini secara otomatis dalam tiga hari.',
|
||||
'native.plans.restore': 'Pulihkan pembelian',
|
||||
'native.plans.restoring': 'Memeriksa pembelian Anda…',
|
||||
'native.plans.restoreNone': 'Tidak ada langganan aktif untuk Apple ID ini.',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Acquisto annullato.',
|
||||
'native.claim.failed': 'L’acquisto non è andato a buon fine. Riprova.',
|
||||
'native.claim.redeemFailed': 'Non siamo riusciti a preparare il tuo TREK. Riprova.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud apre presto. Google Play ti rimborsa automaticamente questo acquisto entro tre giorni.',
|
||||
'native.plans.restore': 'Ripristina acquisti',
|
||||
'native.plans.restoring': 'Controllo dei tuoi acquisti…',
|
||||
'native.plans.restoreNone': 'Nessun abbonamento attivo trovato per questo ID Apple.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': '購入をキャンセルしました。',
|
||||
'native.claim.failed': '購入できませんでした。もう一度お試しください。',
|
||||
'native.claim.redeemFailed': 'TREKを用意できませんでした。もう一度お試しください。',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloudはまもなく開始します。この購入はGoogle Playにより3日以内に自動で返金されます。',
|
||||
'native.plans.restore': '購入を復元',
|
||||
'native.plans.restoring': '購入を確認しています…',
|
||||
'native.plans.restoreNone': 'このApple IDに有効なサブスクリプションは見つかりませんでした。',
|
||||
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': '구매가 취소되었습니다.',
|
||||
'native.claim.failed': '구매가 완료되지 않았습니다. 다시 시도하세요.',
|
||||
'native.claim.redeemFailed': 'TREK을 준비하지 못했습니다. 다시 시도하세요.',
|
||||
'native.claim.closedRefund': 'TREK Cloud가 곧 문을 엽니다. Google Play에서 3일 이내에 이 구매를 자동으로 환불합니다.',
|
||||
'native.plans.restore': '구입 내역 복원',
|
||||
'native.plans.restoring': '구입 내역을 확인하는 중…',
|
||||
'native.plans.restoreNone': '이 Apple ID에서 활성 구독을 찾을 수 없습니다.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Aankoop geannuleerd.',
|
||||
'native.claim.failed': 'De aankoop is niet gelukt. Probeer het opnieuw.',
|
||||
'native.claim.redeemFailed': 'We konden je TREK niet klaarzetten. Probeer het opnieuw.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud opent binnenkort. Google Play betaalt deze aankoop binnen drie dagen automatisch terug.',
|
||||
'native.plans.restore': 'Aankopen herstellen',
|
||||
'native.plans.restoring': 'Je aankopen worden gecontroleerd…',
|
||||
'native.plans.restoreNone': 'Geen actief abonnement gevonden voor deze Apple ID.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Zakup anulowany.',
|
||||
'native.claim.failed': 'Zakup się nie powiódł. Spróbuj ponownie.',
|
||||
'native.claim.redeemFailed': 'Nie udało się przygotować Twojego TREK. Spróbuj ponownie.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud wkrótce startuje. Google Play automatycznie zwróci pieniądze za ten zakup w ciągu trzech dni.',
|
||||
'native.plans.restore': 'Przywróć zakupy',
|
||||
'native.plans.restoring': 'Sprawdzanie zakupów…',
|
||||
'native.plans.restoreNone': 'Nie znaleziono aktywnej subskrypcji dla tego Apple ID.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Покупка отменена.',
|
||||
'native.claim.failed': 'Покупка не прошла. Повторите попытку.',
|
||||
'native.claim.redeemFailed': 'Не удалось настроить ваш TREK. Повторите попытку.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud скоро откроется. Google Play автоматически вернёт деньги за эту покупку в течение трёх дней.',
|
||||
'native.plans.restore': 'Восстановить покупки',
|
||||
'native.plans.restoring': 'Проверяем ваши покупки…',
|
||||
'native.plans.restoreNone': 'Для этого Apple ID не найдено активной подписки.',
|
||||
|
||||
@@ -68,6 +68,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Nákup zrušený.',
|
||||
'native.claim.failed': 'Nákup sa nepodaril. Skúste to znova.',
|
||||
'native.claim.redeemFailed': 'Nepodarilo sa pripraviť váš TREK. Skúste to znova.',
|
||||
'native.claim.closedRefund': 'TREK Cloud čoskoro otvára. Google Play vám tento nákup automaticky vráti do troch dní.',
|
||||
'native.plans.restore': 'Obnoviť nákupy',
|
||||
'native.plans.restoring': 'Kontrolujeme vaše nákupy…',
|
||||
'native.plans.restoreNone': 'Pre toto Apple ID sa nenašlo žiadne aktívne predplatné.',
|
||||
|
||||
@@ -69,6 +69,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Köpet avbröts.',
|
||||
'native.claim.failed': 'Köpet gick inte igenom. Försök igen.',
|
||||
'native.claim.redeemFailed': 'Vi kunde inte göra i ordning din TREK. Försök igen.',
|
||||
'native.claim.closedRefund': 'TREK Cloud öppnar snart. Google Play återbetalar köpet automatiskt inom tre dagar.',
|
||||
'native.plans.restore': 'Återställ köp',
|
||||
'native.plans.restoring': 'Kontrollerar dina köp…',
|
||||
'native.plans.restoreNone': 'Ingen aktiv prenumeration hittades för detta Apple-ID.',
|
||||
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'ยกเลิกการซื้อแล้ว',
|
||||
'native.claim.failed': 'การซื้อไม่สำเร็จ โปรดลองอีกครั้ง',
|
||||
'native.claim.redeemFailed': 'เราตั้งค่า TREK ของคุณไม่สำเร็จ โปรดลองอีกครั้ง',
|
||||
'native.claim.closedRefund': 'TREK Cloud จะเปิดเร็วๆ นี้ Google Play จะคืนเงินการซื้อนี้ให้โดยอัตโนมัติภายในสามวัน',
|
||||
'native.plans.restore': 'กู้คืนการซื้อ',
|
||||
'native.plans.restoring': 'กำลังตรวจสอบการซื้อของคุณ…',
|
||||
'native.plans.restoreNone': 'ไม่พบการสมัครสมาชิกที่ใช้งานอยู่สำหรับ Apple ID นี้',
|
||||
|
||||
@@ -69,6 +69,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Satın alma iptal edildi.',
|
||||
'native.claim.failed': 'Satın alma tamamlanamadı. Lütfen tekrar deneyin.',
|
||||
'native.claim.redeemFailed': 'TREK’inizi hazırlayamadık. Lütfen tekrar deneyin.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud yakında açılıyor. Google Play bu satın alımı üç gün içinde otomatik olarak iade eder.',
|
||||
'native.plans.restore': 'Satın alımları geri yükle',
|
||||
'native.plans.restoring': 'Satın alımlarınız kontrol ediliyor…',
|
||||
'native.plans.restoreNone': 'Bu Apple Kimliği için etkin abonelik bulunamadı.',
|
||||
|
||||
@@ -68,6 +68,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Покупку скасовано.',
|
||||
'native.claim.failed': 'Покупка не пройшла. Повторіть спробу.',
|
||||
'native.claim.redeemFailed': 'Не вдалося налаштувати ваш TREK. Повторіть спробу.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud скоро відкриється. Google Play автоматично поверне кошти за цю покупку протягом трьох днів.',
|
||||
'native.plans.restore': 'Відновити покупки',
|
||||
'native.plans.restoring': 'Перевіряємо ваші покупки…',
|
||||
'native.plans.restoreNone': 'Для цього Apple ID не знайдено активної підписки.',
|
||||
|
||||
@@ -70,6 +70,8 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': 'Đã hủy mua.',
|
||||
'native.claim.failed': 'Giao dịch mua không thành công. Vui lòng thử lại.',
|
||||
'native.claim.redeemFailed': 'Chúng tôi không thể thiết lập TREK của bạn. Vui lòng thử lại.',
|
||||
'native.claim.closedRefund':
|
||||
'TREK Cloud sắp ra mắt. Google Play sẽ tự động hoàn tiền giao dịch mua này trong vòng ba ngày.',
|
||||
'native.plans.restore': 'Khôi phục giao dịch mua',
|
||||
'native.plans.restoring': 'Đang kiểm tra giao dịch mua của bạn…',
|
||||
'native.plans.restoreNone': 'Không tìm thấy gói đăng ký đang hoạt động cho Apple ID này.',
|
||||
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': '已取消購買。',
|
||||
'native.claim.failed': '購買未成功。請重試。',
|
||||
'native.claim.redeemFailed': '我們無法為你設定 TREK。請重試。',
|
||||
'native.claim.closedRefund': 'TREK Cloud 即將開放。Google Play 會在三天內自動退還這筆購買的款項。',
|
||||
'native.plans.restore': '恢復購買項目',
|
||||
'native.plans.restoring': '正在檢查你的購買項目…',
|
||||
'native.plans.restoreNone': '此 Apple ID 沒有找到有效的訂閱。',
|
||||
|
||||
@@ -67,6 +67,7 @@ const native: TranslationStrings = {
|
||||
'native.claim.cancelled': '购买已取消。',
|
||||
'native.claim.failed': '购买未成功。请重试。',
|
||||
'native.claim.redeemFailed': '我们无法为你设置 TREK。请重试。',
|
||||
'native.claim.closedRefund': 'TREK Cloud 即将开放。Google Play 会在三天内自动退还这笔购买的款项。',
|
||||
'native.plans.restore': '恢复购买',
|
||||
'native.plans.restoring': '正在检查你的购买…',
|
||||
'native.plans.restoreNone': '此 Apple ID 下没有找到有效订阅。',
|
||||
|
||||
Reference in New Issue
Block a user