From e872ead6320e7852d5800fdb2362518a2ffe6fc8 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 11 Jan 2016 09:52:46 -0800 Subject: [PATCH 1/2] Implement Brazil coupon --- app/locale/ar.coffee | 4 +-- app/locale/bg.coffee | 4 +-- app/locale/ca.coffee | 4 +-- app/locale/cs.coffee | 4 +-- app/locale/da.coffee | 4 +-- app/locale/de-AT.coffee | 4 +-- app/locale/de-CH.coffee | 4 +-- app/locale/de-DE.coffee | 4 +-- app/locale/el.coffee | 4 +-- app/locale/en-GB.coffee | 4 +-- app/locale/en-US.coffee | 4 +-- app/locale/en.coffee | 4 +-- app/locale/eo.coffee | 4 +-- app/locale/es-419.coffee | 4 +-- app/locale/es-ES.coffee | 4 +-- app/locale/et.coffee | 4 +-- app/locale/fa.coffee | 4 +-- app/locale/fi.coffee | 4 +-- app/locale/fr.coffee | 4 +-- app/locale/gl.coffee | 4 +-- app/locale/he.coffee | 4 +-- app/locale/hi.coffee | 4 +-- app/locale/hu.coffee | 4 +-- app/locale/id.coffee | 4 +-- app/locale/it.coffee | 4 +-- app/locale/ja.coffee | 4 +-- app/locale/ko.coffee | 4 +-- app/locale/lt.coffee | 4 +-- app/locale/mk-MK.coffee | 4 +-- app/locale/ms.coffee | 4 +-- app/locale/my.coffee | 4 +-- app/locale/nb.coffee | 4 +-- app/locale/nl-BE.coffee | 4 +-- app/locale/nl-NL.coffee | 8 ++--- app/locale/nn.coffee | 4 +-- app/locale/pl.coffee | 4 +-- app/locale/pt-BR.coffee | 4 +-- app/locale/pt-PT.coffee | 4 +-- app/locale/ro.coffee | 4 +-- app/locale/ru.coffee | 4 +-- app/locale/sk.coffee | 4 +-- app/locale/sl.coffee | 4 +-- app/locale/sr.coffee | 4 +-- app/locale/sv.coffee | 4 +-- app/locale/th.coffee | 4 +-- app/locale/tr.coffee | 4 +-- app/locale/uk.coffee | 4 +-- app/locale/ur.coffee | 4 +-- app/locale/uz.coffee | 4 +-- app/locale/vi.coffee | 4 +-- app/locale/zh-HANS.coffee | 4 +-- app/locale/zh-HANT.coffee | 4 +-- app/locale/zh-WUU-HANS.coffee | 4 +-- app/locale/zh-WUU-HANT.coffee | 4 +-- app/templates/core/subscribe-modal.jade | 8 +++-- app/templates/play/modal/buy-gems-modal.jade | 2 +- app/views/core/SubscribeModal.coffee | 34 +++++++++--------- app/views/play/modal/BuyGemsModal.coffee | 5 +++ server/payments/subscription_handler.coffee | 36 +++++++++++--------- server/routes/auth.coffee | 2 +- server/routes/stripe.coffee | 6 +++- 61 files changed, 162 insertions(+), 151 deletions(-) diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee index 335720934..a87434b1c 100644 --- a/app/locale/ar.coffee +++ b/app/locale/ar.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi # prompt_body: "Do you want to get more?" prompt_button: "أدخل متجر" recovered: "الأحجار الكريمة السابقة أون استردادها. يرجى تحديث الصفحة." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index cd08c0899..3f9062c6a 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "български език", englishDescri prompt_body: "Искате ли още?" prompt_button: "Влез в Магазина" recovered: "Предишните покупки на скъпоценни камъни са възстановени. Моля опреснете страницата." - price: "x3500 / месец" + price: "x{{gems}} / месец" subscribe: comparison_blurb: "Изостри уменията си в CodeCombat с абонамент!" feature1: "110+ основни нива в 4 свята" feature2: "10 силни нови герои с уникални умения!" feature3: "70+ бонус нива" # {change} - feature4: "3500 скъпоценни камъни бонус всеки месец!" + feature4: "{{gems}} скъпоценни камъни бонус всеки месец!" feature5: "Видео уроци" feature6: "Премиум email поддръжка" feature7: "Частни Кланове" diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index 0f3f967c9..d8033ca75 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr prompt_body: "En vols més?" prompt_button: "Entrar a la botiga" recovered: "S'han recuperat les anteriors compres de gemmes. Si us plaus, recarrega al pàgina." - price: "x3500 / més" + price: "x{{gems}} / més" subscribe: comparison_blurb: "Afina les teves habilitats amb una subscripció a CodeCombat!" feature1: "Més de 60 nivells bàsics a traves de 4 móns" # {change} feature2: "10 nous herois poderosos amb habilitats úniques!" feature3: "Més de 80 nivells bonus" - feature4: "3500 gemmes bonus cada mes!" + feature4: "{{gems}} gemmes bonus cada mes!" feature5: "Vídeo tutorials" feature6: "Suport Premium per correu electrònic" feature7: "Privat Clans" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index 495232d55..283de5cd1 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr prompt_body: "Chcete získat více?" prompt_button: "Vstoupit do obchodu" recovered: "Obnovení již zakoupených drahokamů proběhlo úspěšně. Aktualizujte stránku prosím." - price: "x3500 / měs." + price: "x{{gems}} / měs." subscribe: comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" feature1: "60+ základních úrovní napříč 4 světy" # {change} feature2: "7 silných nových hrdinů s jedinečnými dovednostmi!" # {change} feature3: "30+ bonusových úrovní" # {change} - feature4: "3500 bonusových drahokamů každý měsíc!" + feature4: "{{gems}} bonusových drahokamů každý měsíc!" feature5: "Video tutoriály" feature6: "Premiová e-mailová podpora" feature7: "Soukromé Klany" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index 0808d06f7..8cdc18e06 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee index 23cd22f54..ff2f795b2 100644 --- a/app/locale/de-AT.coffee +++ b/app/locale/de-AT.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription: prompt_body: "Möchtest du mehr?" prompt_button: "Shop betreten" recovered: "Voriger Juwelenkauf wiederhergestellt. Bitte die Seite neu laden." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee index d6335082f..8d8ea4f61 100644 --- a/app/locale/de-CH.coffee +++ b/app/locale/de-CH.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Dütsch (Schwiiz)", englishDescription: "Ge prompt_body: "Wetsch mee chaufe?" prompt_button: "zum Shop" recovered: "Früenere Ichauf zruggerstatet. Bitte dSite neu lade!" -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: comparison_blurb: "Verschärf dins Chönne midme CodeCombat Abonement." feature1: "80+ basis levels in 4 Weltete!" # {change} # feature2: "10 powerful new heroes with unique skills!" feature3: "50+ bonus levels" # {change} -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" feature5: "Video Aleitige" feature6: "Premium Email Hilf" # feature7: "Private Clans" diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee index 1c0127355..033b7d1cb 100644 --- a/app/locale/de-DE.coffee +++ b/app/locale/de-DE.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription: prompt_body: "Benötigst du mehr?" prompt_button: "Laden betreten" recovered: "Vorangegangener Edelsteinkauf rückgängig gemacht. Aktualisiere bitte die Seite." - price: "x3500 / Monat" + price: "x{{gems}} / Monat" subscribe: comparison_blurb: "Verbessere deine Fähigkeiten mit einem CodeCombat Abonnement" feature1: "60+ Basislevel in 4 Gebieten" # {change} feature2: "7 mächtige neue Helden mit einzigartigen Fertigkeiten" # {change} feature3: "30+ Bonuslevel" # {change} - feature4: "3500 Bonusedelsteine jeden Monat!" + feature4: "{{gems}} Bonusedelsteine jeden Monat!" feature5: "Videoanleitungen" feature6: "Premium Emailsupport" # feature7: "Private Clans" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index 75226b459..28612bffc 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre prompt_body: "Θέλεις να πάρεις περισσότερα;" prompt_button: "Μπες στο κατάστημα" recovered: "Ανακτήθηκε η προηγούμενη αγορά πετραδιών. Παρακαλώ ανανέωσε τη σελίδα." - price: "x3500 / μήνα" + price: "x{{gems}} / μήνα" subscribe: comparison_blurb: "Ακόνησε τις ικανότητές σου με μια συνδρομή στο CodeCombat!" feature1: "110+ βασικά επίπεδα που εκτείνονται σε 4 κόσμους" feature2: "10 παντοδύναμοι νέοι ήρωες με μοναδικές ικανότητες!" feature3: "80+ επίπεδα δώρο" - feature4: "3500 πετράδια δώρο κάθε μήνα!" + feature4: "{{gems}} πετράδια δώρο κάθε μήνα!" feature5: "Βίντεο Βοηθήματα" feature6: "Προνομιακή υποστήριξη μέσω ηλεκτρονικού ταχυδρομείου" feature7: "Ιδιωτικές Φατρίες" diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee index 100b6a2c0..fa383d144 100644 --- a/app/locale/en-GB.coffee +++ b/app/locale/en-GB.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee index 36acdef83..a7f1db002 100644 --- a/app/locale/en-US.coffee +++ b/app/locale/en-US.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 823d17cdb..f567ac11a 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -397,14 +397,14 @@ prompt_body: "Do you want to get more?" prompt_button: "Enter Shop" recovered: "Previous gems purchase recovered. Please refresh the page." - price: "x3500 / mo" + price: "x{{gems}} / mo" subscribe: comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" feature1: "110+ basic levels across 4 worlds" feature2: "10 powerful new heroes with unique skills!" feature3: "80+ bonus levels" - feature4: "3500 bonus gems every month!" + feature4: "{{gems}} bonus gems every month!" feature5: "Video tutorials" feature6: "Premium email support" feature7: "Private Clans" diff --git a/app/locale/eo.coffee b/app/locale/eo.coffee index 6fcde6626..c9ff77b71 100644 --- a/app/locale/eo.coffee +++ b/app/locale/eo.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Esperanto", englishDescription: "Esperanto" # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 9a1236826..0193b28a3 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip prompt_body: "¿Quieres obtener más?" prompt_button: "Entrar al mercado" recovered: "Se recuperaron las anteriores compras de gemas. Por favor recarga la página" - price: "x3500 / mes" + price: "x{{gems}} / mes" subscribe: comparison_blurb: "Agudiza tus habilidades con la suscripción a CodeCombat!" feature1: "Más de 110 niveles basicos a lo largo de 4 mundos" feature2: "10 poderosos nuevos heroés con habilidades unicas!" feature3: "Más de 70 niveles extras" # {change} - feature4: "3500 gemas de bono cada mes!" + feature4: "{{gems}} gemas de bono cada mes!" feature5: "Video tutoriales" feature6: "Soporte Premium vía email" feature7: "Clan Privado" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index 4354cef5b..99e40a169 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis prompt_body: "¿Quieres obtener más?" prompt_button: "Ingresa a la tienda" recovered: "Las gemas compradas con anterioridad han sido recuperadas. Por favor, actualiza la página." - price: "x3500 / mes" + price: "x{{gems}} / mes" subscribe: comparison_blurb: "¡Mejora tus habilidades con una suscripción a CodeCombat!" feature1: "Más de 110 niveles básicos pasando por 4 mundos" feature2: "¡10 héroes nuevos con poderes únicos!" feature3: "Más de 70 niveles extra" # {change} - feature4: "¡3500 gemas extra cada mes!" + feature4: "¡{{gems}} gemas extra cada mes!" feature5: "Vídeo tutoriales" feature6: "Soporte electrónico Premium" feature7: "Clanes privados" diff --git a/app/locale/et.coffee b/app/locale/et.coffee index 88de4f113..1316183c8 100644 --- a/app/locale/et.coffee +++ b/app/locale/et.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Eesti", englishDescription: "Estonian", tra # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index ca2857b65..0719bd8f9 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee index 99057722d..398eb5cfc 100644 --- a/app/locale/fi.coffee +++ b/app/locale/fi.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran prompt_body: "Haluatko ostaa lisää?" prompt_button: "Siirry kauppaan" recovered: "Aiempi jalokiviostos palautettu. Ole hyvä ja päivitä sivu." - price: "x3500 / kk" + price: "x{{gems}} / kk" subscribe: comparison_blurb: "Teroita kykyjäsi CodeCombat kuukausitilauksella!" feature1: "110+ perustasoa 4:ssä maailmassa" feature2: "10 mahtavaa uutta sankaria erilaisine kykyineen!" feature3: "70+ lisätasoa" # {change} - feature4: "3500 jalokiveä joka kuukausi!" + feature4: "{{gems}} jalokiveä joka kuukausi!" feature5: "Video-oppaat" feature6: "Premium sähköpostituki" feature7: "Yksityisklaanit" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index b279069fd..a6dfa25aa 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "français", englishDescription: "French", t prompt_body: "En voulez-vous plus ?" prompt_button: "Entrer dans la boutique" recovered: "Gemmes précédemment achetées récupérées. Merci de rafraîchir la page." - price: "x3500 / mo" + price: "x{{gems}} / mo" subscribe: comparison_blurb: "Aiguisez vos compétences avec un abonnement CodeCombat !" feature1: "Plus de 60 niveaux au travers de 4 mondes" # {change} feature2: "7 puissants nouveaux héros avec des compétences uniques !" # {change} feature3: "Plus de 30 niveaux bonus" # {change} - feature4: "3500 gemmes bonus tous les mois !" + feature4: "{{gems}} gemmes bonus tous les mois !" feature5: "Tutoriels vidéo" feature6: "Assitance par e-mail dédiée" feature7: "Clans privés" diff --git a/app/locale/gl.coffee b/app/locale/gl.coffee index b0bd20e8e..e921fae2c 100644 --- a/app/locale/gl.coffee +++ b/app/locale/gl.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Galego", englishDescription: "Galician", tr # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/he.coffee b/app/locale/he.coffee index a825925b1..882452552 100644 --- a/app/locale/he.coffee +++ b/app/locale/he.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", prompt_body: "?רוצה לקבל עוד" prompt_button: "היכנס לחנות" recovered: ".רכישה אחרונה שוחזרה. טען את הדף מחדש בבקשה" - price: "x3500 לחודש" + price: "x{{gems}} לחודש" subscribe: comparison_blurb: ".CodeCombatחדד את כישוריך עם מנוי ל" feature1: "60+ שלבים בסיסיים ב 4 עולמות שונים." # {change} feature2: "!עם כישורים מיוחדים גיבורים עוצמתיים חדשים 7" # {change} feature3: "30+ שלבי בונוס" # {change} - feature4: "!בחינם כל חודש 3500 אבני חן" + feature4: "!בחינם כל חודש {{gems}} אבני חן" feature5: "הדרכות וידאו" feature6: "תמיכת מייל בעדיפות ראשונה" feature7: "פרטיים שבטים" diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee index 4f3b10258..91d47384c 100644 --- a/app/locale/hi.coffee +++ b/app/locale/hi.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 1d4446a9c..f99e4571f 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t prompt_body: "Szeretnél többet?" prompt_button: "Lépj be a boltba" recovered: "Az előző drágakő vásárlás helyreállt. Kérlek frissítsd az oldalt." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: comparison_blurb: "Élesítsd képességeid CodeCombat feliratkozással!" feature1: "60+ alap pálya, 4 világon át" # {change} feature2: "7 erőteljes új hős egyedi képességekkel!" # {change} feature3: "30+ bónusz pálya" # {change} - feature4: "3500 bónusz drágakő minden hónapban!" + feature4: "{{gems}} bónusz drágakő minden hónapban!" feature5: "Videó oktatóanyagok" feature6: "Prémium email támogatás" # feature7: "Private Clans" diff --git a/app/locale/id.coffee b/app/locale/id.coffee index 4e9fb5488..31b78ee43 100644 --- a/app/locale/id.coffee +++ b/app/locale/id.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index 4a59f0b15..430adea2f 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t prompt_body: "Ne vuoi comprare altre?" prompt_button: "Entra nel negozio" recovered: "Acquisto precedente recuperato. Ricaricare la pagina." - price: "x3500 / mese" + price: "x{{gems}} / mese" subscribe: comparison_blurb: "Aumenta le tue competenze con un abbonamento a CodeCombat!" feature1: "80+ livelli base in 4 mondi" # {change} feature2: "7 potenti nuovi eroi con capacità uniche!" # {change} feature3: "50+ livelli bonus" # {change} - feature4: "3500 gemme bonus ogni mese!" + feature4: "{{gems}} gemme bonus ogni mese!" feature5: "Video tutorial" feature6: "Supporto via email premium" feature7: "Clan privati" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index fac55c734..37b293401 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", prompt_body: "もっと購入しますか?" prompt_button: "ショップに入る" recovered: "前のジェム購入をリカバリーしました。ページを更新してください。" - price: "x3500 / 月" + price: "x{{gems}} / 月" subscribe: comparison_blurb: "CodeCombatへ課金してスキルを磨きましょう!" feature1: "110以上の基本レベルが4つの世界に" # {change} feature2: "10人のパワフルな ニューヒーロー とユニークなスキル!" # {change} feature3: "70以上のボーナスレベル" # {change} - feature4: "3500のジェムが毎月ボーナス!" + feature4: "{{gems}}のジェムが毎月ボーナス!" feature5: "ビデオチュートリアル" feature6: "プレミアムメールサポート" feature7: "プライベートクラン" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index 5b5c955db..fe9c319ab 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t prompt_body: "gem이 더 필요하신가요?" prompt_button: "Enter Shop" recovered: "gem 구매후 브라우져를 새로고침 하세요." - price: "x3500 / 한달" + price: "x{{gems}} / 한달" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee index 07e539cda..aa0077111 100644 --- a/app/locale/lt.coffee +++ b/app/locale/lt.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith prompt_body: "Ar norite gauti daugiau?" prompt_button: "Į Parduotuvę" recovered: "Atstatyta deimantų pirkimo operacija. Prašome pakraukite puslapį iš naujo." - price: "x3500 / mėn" + price: "x{{gems}} / mėn" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/mk-MK.coffee b/app/locale/mk-MK.coffee index 14a12f73d..19dcead5f 100644 --- a/app/locale/mk-MK.coffee +++ b/app/locale/mk-MK.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Македонски", englishDescription: prompt_body: "Дали сакаш да земеш повеќе?" prompt_button: "Влези во продавницата" recovered: "Претходното купување на скапоцени камења е вратено од загуба. Те молам 'освежи' ја страната." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee index 245b294ba..5b3dabf3d 100644 --- a/app/locale/ms.coffee +++ b/app/locale/ms.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/my.coffee b/app/locale/my.coffee index 4085985f1..45673d000 100644 --- a/app/locale/my.coffee +++ b/app/locale/my.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "မြန်မာစကား", englishDes # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index 3668ab100..9084d5451 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg prompt_body: "Har du lyst på flere?" prompt_button: "Til Butikken" recovered: "Tidligere juvelkjøp hentet. Vennligst last siden på nytt" -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: comparison_blurb: "Spiss dine kunnskaper med et CodeCombat abonnement!" feature1: "60+ grunnleggende brett fordelt på 4 verdener" # {change} feature2: "7 kraftfulle nye helter med unike ferdigheter!" # {change} feature3: "30+ bonusbrett" # {change} - feature4: "3500 bonusjuveler hver måned!" + feature4: "{{gems}} bonusjuveler hver måned!" feature5: "Videoveiledninger" feature6: "Premium e-poststøtte" # feature7: "Private Clans" diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee index 535da218b..ff3000fb7 100644 --- a/app/locale/nl-BE.coffee +++ b/app/locale/nl-BE.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription: prompt_body: "Wil je er meer verkrijgen?" prompt_button: "Ga binnen in de winkel" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee index 840003ade..0d07398a5 100644 --- a/app/locale/nl-NL.coffee +++ b/app/locale/nl-NL.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription prompt_body: "Wil je meer krijgen?" prompt_button: "Naar de winkel" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: comparison_blurb: "Verbeter je vaardigheden met een abonement op CodeCombat!" feature1: "meer dan 110+ basislevels over 4 werelden" feature2: "10 sterke nieuwe helden met unieke vaardigheden!" feature3: "70+ bonuslevels" # {change} - feature4: "3500 bonus edelstenen elke maand!" + feature4: "{{gems}} bonus edelstenen elke maand!" feature5: "Video cursussen" feature6: "Hoogwaardige e-mail ondersteuning" feature7: "Besloten Clans" @@ -513,7 +513,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription current_value: "Huidige waarde" default_value: "Standaard waarde" parameters: "Parameters" -# returns: "Returns" +# returns: "Returns" granted_by: "Verleend door" save_load: @@ -671,7 +671,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription email_subscriptions: "E-mail Abonnementen" email_subscriptions_none: "Geen E-mail Abonnementen." email_announcements: "Aankondigingen" - email_announcements_description: "Ontvang e-mails over het laatste nieuws en de ontwikkelingen bij CodeCombat." + email_announcements_description: "Ontvang e-mails over het laatste nieuws en de ontwikkelingen bij CodeCombat." email_notifications: "Notificaties" email_notifications_summary: "Instellingen voor gepersonaliseerde, automatische meldingen via e-mail omtrent je activiteit op CodeCombat." email_any_notes: "Alle Meldingen" diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee index 5dceee316..8fcbb3798 100644 --- a/app/locale/nn.coffee +++ b/app/locale/nn.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Norsk Nynorsk", englishDescription: "Norweg # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index b6b113a54..61174eda5 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "polski", englishDescription: "Polish", tran prompt_body: "Chcesz zdobyć więcej?" prompt_button: "Wejdź do sklepu" recovered: "Przywrócono poprzednie zakupy. Prosze odświeżyć stronę." - price: "x3500 / mieś." + price: "x{{gems}} / mieś." subscribe: comparison_blurb: "Popraw swoje umiejętności z subskrypcją CodeCombat!" feature1: "Ponad 100 poziomów w 4 różnych śwoatach" # {change} feature2: "10 potężnych, nowych bohaterów z unikalnymi umiejętnościami!" # {change} feature3: "Ponad 70 bonusowych poziomów" # {change} - feature4: "Dodatkowe 3500 klejnotów co miesiąc!" + feature4: "Dodatkowe {{gems}} klejnotów co miesiąc!" feature5: "Poradniki wideo" feature6: "Priorytetowe wsparcie przez e-mail" feature7: "Prywatne Klany" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 0c6a29815..5101a3c03 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Português do Brasil", englishDescription: prompt_body: "Você quer adquirir mais gemas?" prompt_button: "Entrar na loja" recovered: "Gemas das compras anteriores recuperadas. Por favor atualize a pagina." - price: "x3500 / mês" + price: "x{{gems}} / mês" subscribe: comparison_blurb: "Afine suas habilidades com uma assinatura CodeCombat!" feature1: "Mais de 60 níveis básicos entre 4 mundos" # {change} feature2: "7 poderosos novos heróis com habilidades únicas!" # {change} feature3: "Mais de 30 níveis bônus" # {change} - feature4: "3500 gemas bônus todo mês!" + feature4: "{{gems}} gemas bônus todo mês!" feature5: "Vídeo tutorials" feature6: "Suporte via e-mail Premium" feature7: "Clãs Privados" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 475b8a38d..c68c8f2dd 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: prompt_body: "Queres obter mais?" prompt_button: "Entra na Loja" recovered: "A compra de gemas anterior foi recuperada. Por favor atualiza a página." - price: "x3500 / mês" + price: "x{{gems}} / mês" subscribe: comparison_blurb: "Aperfeiçoa as tuas habilidades com uma subscrição do CodeCombat!" feature1: "110+ níveis básicos dispersos por 4 mundos" feature2: "10 heróis novos e poderosos com habilidades únicas!" feature3: "80+ níveis de bónus" - feature4: "3500 gemas de bónus por mês!" + feature4: "{{gems}} gemas de bónus por mês!" feature5: "Tutoriais em vídeo" feature6: "Apoio por e-mail prioritário" feature7: "Clãs Privados" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index bd09656e0..12451626a 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman prompt_body: "Vrei mai multe?" prompt_button: "Intră în magazin." recovered: "Pietre Prețioase cumpărate anterior recuperate.Va rugăm să dați refresh la pagină." - price: "x3500 / mo" + price: "x{{gems}} / mo" subscribe: comparison_blurb: "Îmbunătățeșteți abilitățile cu abonamentul CodeCombat" feature1: "80+ de nivele de bază în 4 lumi diferite!" # {change} feature2: "7 Eroi Noi puternici, cu skilluri unice!" # {change} feature3: "60+ nivele bonus" # {change} - feature4: "3500 de Pietre Prețioase bonus în fiecare lună!" + feature4: "{{gems}} de Pietre Prețioase bonus în fiecare lună!" feature5: "Tutoriale Video" feature6: "Suport e-mail premium" feature7: "Clanuri private" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 0926a5bdd..e4012da87 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi prompt_body: "Хотите еще?" prompt_button: "Войти в магазин" recovered: "Предыдущие покупки самоцветов восстановлены. Пожалуйста, обновите страницу." - price: "x3500 / месяц" + price: "x{{gems}} / месяц" subscribe: comparison_blurb: "Отточите свое мастерство благодаря подписке на CodeCombat!" feature1: "80+ основных уровней на просторах 4-х миров" # {change} feature2: "7 могущественных новых героев с уникальными способностями!" # {change} feature3: "60+ дополнительных уровней" # {change} - feature4: "3500 бонусных самоцветов каждый месяц!" + feature4: "{{gems}} бонусных самоцветов каждый месяц!" feature5: "Обучающие видеоролики" feature6: "Эксклюзивная поддержка по электронной почте" feature7: "Частные Кланы" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 1e2e2f92e..cd97a491b 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", prompt_body: "Chcete získať viac?" prompt_button: "Vstúpiť do obchodu" recovered: "Obnovenie už zakúpených drahokamov prebehlo úspěšne. Aktualizujte stránku prosím." - price: "x3500 / mesiac" + price: "x{{gems}} / mesiac" subscribe: comparison_blurb: "Uč sa dôkladnejšie vďaka predplatnému !" feature1: "60+ základných úrovní v štyroch svetoch" # {change} feature2: "7 mocných new hrdinov s jedinečnými schopnosťami!" # {change} feature3: "30+ bonusových úrovní" # {change} - feature4: "3500 bonusových diamantov každý mesiac !" + feature4: "{{gems}} bonusových diamantov každý mesiac !" feature5: "Video tutoriály" feature6: "Prémiová emailová podpora" # feature7: "Private Clans" diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee index e3ffe7511..d17f60892 100644 --- a/app/locale/sl.coffee +++ b/app/locale/sl.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index aaa29c26c..4f0261df9 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index 35a9eeee5..eae648f5d 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr prompt_body: "Vill du skaffa flera?" prompt_button: "Gå till affären" recovered: "Föregående köp av ädelstenar återskapat. Var vänlig och uppdatera sidan." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/th.coffee b/app/locale/th.coffee index 8027a476a..0db1c69ec 100644 --- a/app/locale/th.coffee +++ b/app/locale/th.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index 372164084..8c1b832ad 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index c3ac2d8f7..27d842a2c 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Українська", englishDescription: prompt_body: "Хочете отримати ще?" prompt_button: "Увійти до крамниці" recovered: "Попередні покупки самоцвітів відновлені. Будь ласка, поновіть сторінку." - price: "x3500 / міс" + price: "x{{gems}} / міс" subscribe: comparison_blurb: "Відточіть свої навички завдяки підписці на CodeCombat!" feature1: "Більше 110 основних рівней на просторах 4 світів" feature2: "10 могутніх нових героїв з унікальними здібностями!" feature3: "Більше 80-ти бонусних рівнів" - feature4: "3500 бонусних самоцвітів кожного місяця!" + feature4: "{{gems}} бонусних самоцвітів кожного місяця!" feature5: "Навчальні відеоролики" feature6: "Екслюзивна підтримка по електронній пошті" feature7: "Приватні клани" diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee index 83ef0ba44..1d9040d90 100644 --- a/app/locale/ur.coffee +++ b/app/locale/ur.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu", # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/uz.coffee b/app/locale/uz.coffee index b5c883eaf..283b9b2d7 100644 --- a/app/locale/uz.coffee +++ b/app/locale/uz.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "O'zbekcha", englishDescription: "Uzbek", tr # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 516524119..42094b48f 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn prompt_body: "Ban có muốn nhiều ngọc hơn không ?" prompt_button: "Vào cửa hàng" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" feature2: "7 nhât vật mới mạnh mẽ với những kĩ năng đặc biệt!" # {change} # feature3: "80+ bonus levels" - feature4: "Được thưởng thêm 3500 ngọc mỗi tháng!" + feature4: "Được thưởng thêm {{gems}} ngọc mỗi tháng!" feature5: "Những video hướng dẫn qua bàn" feature6: "Sự hỗ trợ tận tình qua email" # feature7: "Private Clans" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index afcf533b9..8004077f7 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese prompt_body: "还需要更多吗?" prompt_button: "进入商店" recovered: "之前购买的宝石已恢复。请刷新页面。" - price: "x3500 / 月" + price: "x{{gems}} / 月" subscribe: comparison_blurb: "亲,订阅CodeCombat,大力的提升您的技能!" feature1: "110+ 基本关卡(4个世界)" feature2: "10 个强大 英雄以及各式非凡技能!" feature3: "80+ 奖励关卡" - feature4: "每月享有3500额外宝石" + feature4: "每月享有{{gems}}额外宝石" feature5: "视频教学" feature6: "专业邮件支援" feature7: "私人 部落" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index 712217e57..2f1403e72 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese prompt_body: "想要取得更多?" prompt_button: "進入商店" recovered: "先前購買的寶石已回復,請重新載入頁面。" - price: "x3500 / 月" + price: "x{{gems}} / 月" subscribe: comparison_blurb: "訂閱 CodeCombat 來磨練您的技巧!" feature1: "110 個以上的基本關卡散佈在4張地圖中" feature2: "10 個強壯的新英雄並每位都有不同技巧!" feature3: "80 個以上的額外關卡" - feature4: "每個月3500顆額外寶石!" + feature4: "每個月{{gems}}顆額外寶石!" feature5: "影片教學" feature6: "頂級信箱支援" feature7: "私人 部落" diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee index bc742ddcd..52c619d2b 100644 --- a/app/locale/zh-WUU-HANS.coffee +++ b/app/locale/zh-WUU-HANS.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee index 67617c384..e86dfc91d 100644 --- a/app/locale/zh-WUU-HANT.coffee +++ b/app/locale/zh-WUU-HANT.coffee @@ -397,14 +397,14 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio # prompt_body: "Do you want to get more?" # prompt_button: "Enter Shop" # recovered: "Previous gems purchase recovered. Please refresh the page." -# price: "x3500 / mo" +# price: "x{{gems}} / mo" # subscribe: # comparison_blurb: "Sharpen your skills with a CodeCombat subscription!" # feature1: "110+ basic levels across 4 worlds" # feature2: "10 powerful new heroes with unique skills!" # feature3: "80+ bonus levels" -# feature4: "3500 bonus gems every month!" +# feature4: "{{gems}} bonus gems every month!" # feature5: "Video tutorials" # feature6: "Premium email support" # feature7: "Private Clans" diff --git a/app/templates/core/subscribe-modal.jade b/app/templates/core/subscribe-modal.jade index 978ca5890..fec7039f7 100644 --- a/app/templates/core/subscribe-modal.jade +++ b/app/templates/core/subscribe-modal.jade @@ -53,7 +53,7 @@ td.center-ok span.glyphicon.glyphicon-ok tr - td.feature-description + td.feature-description.gem-amount span(data-i18n="[html]subscribe.feature4") if !me.isOnPremiumServer() td.free-cell @@ -83,8 +83,10 @@ #parents-info(data-i18n="subscribe.parents") #payment-methods-info(data-i18n="subscribe.payment_methods") - button.btn.btn-lg.btn-illustrated.parent-button(data-i18n="subscribe.parent_button") - button.btn.btn-lg.btn-illustrated.sale-button(data-i18n="[title]subscribe.sale_button_title", data-i18n="subscribe.sale_button") + if !me.isOnPremiumServer() + button.btn.btn-lg.btn-illustrated.parent-button(data-i18n="subscribe.parent_button") + if view.yearProduct + button.btn.btn-lg.btn-illustrated.sale-button(data-i18n="[title]subscribe.sale_button_title", data-i18n="subscribe.sale_button") button.btn.btn-lg.btn-illustrated.purchase-button(data-i18n="subscribe.subscribe_title") if view.state === 'declined' diff --git a/app/templates/play/modal/buy-gems-modal.jade b/app/templates/play/modal/buy-gems-modal.jade index 157b6dfb9..c67c31ca0 100644 --- a/app/templates/play/modal/buy-gems-modal.jade +++ b/app/templates/play/modal/buy-gems-modal.jade @@ -20,7 +20,7 @@ span= product.get('priceString') .product - h4(data-i18n="buy_gems.price") x3500 / mo + h4.subscription-gem-amount x{{gems}} / mo h3(data-i18n="account.subscription") if me.isPremium() button.disabled.start-subscription-button.btn.btn-lg.btn-illustrated.btn-success diff --git a/app/views/core/SubscribeModal.coffee b/app/views/core/SubscribeModal.coffee index 0d5316276..166a0ef4d 100644 --- a/app/views/core/SubscribeModal.coffee +++ b/app/views/core/SubscribeModal.coffee @@ -31,6 +31,9 @@ module.exports = class SubscribeModal extends ModalView onLoaded: -> @basicProduct = @products.findWhere { name: 'basic_subscription' } @yearProduct = @products.findWhere { name: 'year_subscription' } + if countrySpecificProduct = @products.findWhere { name: "#{me.get('country')}_basic_subscription" } + @basicProduct = countrySpecificProduct + @yearProduct = @products.findWhere { name: "#{me.get('country')}_year_subscription" } # probably null super() afterRender: -> @@ -38,6 +41,8 @@ module.exports = class SubscribeModal extends ModalView @setupParentButtonPopover() @setupParentInfoPopover() @setupPaymentMethodsInfoPopover() + if @basicProduct + @$el.find('.gem-amount').html $.i18n.t('subscribe.feature4').replace('{{gems}}', @basicProduct.get('gems')) setupParentButtonPopover: -> popoverTitle = $.i18n.t 'subscribe.parent_email_title' @@ -62,7 +67,7 @@ module.exports = class SubscribeModal extends ModalView popoverContent = "

" + $.i18n.t('subscribe.parents_blurb1', nLevels: levelsCompleted) + "

" popoverContent += "

" + $.i18n.t('subscribe.parents_blurb1a') + "

" popoverContent += "

" + $.i18n.t('subscribe.parents_blurb2') + "

" - price = (@products.findWhere({'name': 'basic_subscription'}).get('amount') / 100).toFixed(2) + price = (@basicProduct.get('amount') / 100).toFixed(2) # TODO: Update i18next and use its own interpolation system instead popoverContent = popoverContent.replace('{{price}}', price) popoverContent += "

" + $.i18n.t('subscribe.parents_blurb3') + "

" @@ -80,13 +85,16 @@ module.exports = class SubscribeModal extends ModalView setupPaymentMethodsInfoPopover: -> return unless @products.size() popoverTitle = $.i18n.t('subscribe.payment_methods_title') - three_month_price = (@products.findWhere({'name': 'basic_subscription'}).get('amount') * 3 / 100).toFixed(2) - year_price = (@products.findWhere({name: 'year_subscription'}).get('amount') / 100).toFixed(2) + threeMonthPrice = (@basicProduct.get('amount') * 3 / 100).toFixed(2) + if @yearProduct + yearPrice = (@yearProduct.get('amount') / 100).toFixed(2) + else + yearPrice = (@basicProduct.get('amount') * 12 / 100).toFixed(2) popoverTitle += '' popoverContent = "

" + $.i18n.t('subscribe.payment_methods_blurb1') + "

" # TODO: Update i18next and use its own interpolation system instead - popoverContent = popoverContent.replace('{{three_month_price}}', three_month_price) - popoverContent = popoverContent.replace('{{year_price}}', year_price) + popoverContent = popoverContent.replace('{{three_month_price}}', threeMonthPrice) + popoverContent = popoverContent.replace('{{year_price}}', yearPrice) popoverContent += "

" + $.i18n.t('subscribe.payment_methods_blurb2') + " support@codecombat.com." @$el.find('#payment-methods-info').popover( animation: true @@ -123,7 +131,7 @@ module.exports = class SubscribeModal extends ModalView @$el.find('.parent-button').popover('hide') onClickPurchaseButton: (e) -> - return unless @basicProduct and @yearProduct + return unless @basicProduct @playSound 'menu-button-click' return @openModalView new AuthModal() if me.get('anonymous') application.tracker?.trackEvent 'Started subscription purchase' @@ -134,16 +142,6 @@ module.exports = class SubscribeModal extends ModalView alipayReusable: true } - # SALE LOGIC - # overwrite amount with sale price - # maybe also put in another description with details about how long it lasts, etc - # NOTE: Do not change this price without updating the context.price in getRenderData - # NOTE: And, the popover content if necessary - #options = { - # description: 'Monthly Subscription (HoC sale)' - # amount: 399 - #} - @purchasedAmount = options.amount stripeHandler.open(options) @@ -203,13 +201,13 @@ module.exports = class SubscribeModal extends ModalView @state = 'unknown_error' @stateMessage = "Uknown problem occurred while processing Stripe request" - onSubscriptionSuccess: -> + onSubscriptionSuccess: => application.tracker?.trackEvent 'Finished subscription purchase', value: @purchasedAmount Backbone.Mediator.publish 'subscribe-modal:subscribed', {} @playSound 'victory' @hide() - onSubscriptionError: (user, response, options) -> + onSubscriptionError: (user, response, options) => console.error 'We got an error subscribing with Stripe from our server:', response application.tracker?.trackEvent 'Failed to finish subscription purchase', status: options.xhr?.status, value: @purchasedAmount stripe = me.get('stripe') ? {} diff --git a/app/views/play/modal/BuyGemsModal.coffee b/app/views/play/modal/BuyGemsModal.coffee index 2cdea7a75..0f153a7f9 100644 --- a/app/views/play/modal/BuyGemsModal.coffee +++ b/app/views/play/modal/BuyGemsModal.coffee @@ -37,6 +37,9 @@ module.exports = class BuyGemsModal extends ModalView @render() onLoaded: -> + @basicProduct = @products.findWhere { name: 'basic_subscription' } + if countrySpecificProduct = @products.findWhere { name: "#{me.get('country')}_basic_subscription" } + @basicProduct = countrySpecificProduct @products.reset @products.filter (product) -> _.string.startsWith(product.get('name'), 'gems_') super() @@ -44,6 +47,8 @@ module.exports = class BuyGemsModal extends ModalView super() return unless @supermodel.finished() @playSound 'game-menu-open' + if @basicProduct + @$el.find('.subscription-gem-amount').text $.i18n.t('buy_gems.price').replace('{{gems}}', @basicProduct.get('gems')) onHidden: -> super() diff --git a/server/payments/subscription_handler.coffee b/server/payments/subscription_handler.coffee index e4cb53d88..0fb7b191e 100644 --- a/server/payments/subscription_handler.coffee +++ b/server/payments/subscription_handler.coffee @@ -139,28 +139,28 @@ class SubscriptionHandler extends Handler if err @logSubscriptionError(user, "Purchase year sale Stripe cancel subscription error: #{JSON.stringify(err)}") return @sendDatabaseError(res, err) - + Product.findOne({name: 'year_subscription'}).exec (err, product) => return @sendDatabaseError(res, err) if err return @sendNotFoundError(res, 'year_subscription product not found') if not product - + metadata = type: req.body.type userID: req.user._id + '' gems: product.get('gems') timestamp: parseInt(req.body.stripe?.timestamp) description: req.body.description - + StripeUtils.createCharge req.user, product.get('amount'), metadata, (err, charge) => if err @logSubscriptionError(req.user, "Purchase year sale create charge: #{JSON.stringify(err)}") return @sendDatabaseError(res, err) - + StripeUtils.createPayment req.user, charge, (err, payment) => if err @logSubscriptionError(req.user, "Purchase year sale create payment: #{JSON.stringify(err)}") return @sendDatabaseError(res, err) - + # Add terminal subscription to User with extensions for existing subscriptions stripeInfo = _.cloneDeep(req.user.get('stripe') ? {}) endDate = new Date() @@ -171,14 +171,14 @@ class SubscriptionHandler extends Handler endDate.setUTCFullYear(endDate.getUTCFullYear() + 1) stripeInfo.free = endDate.toISOString().substring(0, 10) req.user.set('stripe', stripeInfo) - + # Add year's worth of gems to User purchased = _.clone(req.user.get('purchased')) purchased ?= {} purchased.gems ?= 0 purchased.gems += parseInt(charge.metadata.gems) req.user.set('purchased', purchased) - + req.user.save (err, user) => if err @logSubscriptionError(req.user, "User save error: #{JSON.stringify(err)}") @@ -248,18 +248,18 @@ class SubscriptionHandler extends Handler endDate = new moment(stripeSubscriptionPeriodEndDate) else if _.isString(stripeInfo.free) and new moment().isBefore(new moment(stripeInfo.free)) endDate = new moment(stripeInfo.free) - + endDate = endDate.add(months, 'months') stripeInfo.free = endDate.toISOString().substring(0, 10) req.user.set('stripe', stripeInfo) - + # Add gems to User purchased = _.clone(req.user.get('purchased')) purchased ?= {} purchased.gems ?= 0 purchased.gems += product.get('gems') * months req.user.set('purchased', purchased) - + req.user.save (err, user) => if err @logSubscriptionError(req.user, "User save error: #{JSON.stringify(err)}") @@ -366,6 +366,8 @@ class SubscriptionHandler extends Handler else couponID = user.get('stripe')?.couponID + if user.get('country') is 'brazil' + couponID ?= 'brazil' # SALE LOGIC # overwrite couponID with another for everyone-sales #couponID = 'hoc_399' if not couponID @@ -436,7 +438,7 @@ class SubscriptionHandler extends Handler purchased.gems ?= 0 purchased.gems += product.get('gems') # TODO: Put actual subscription amount here user.set('purchased', purchased) - + user.save (err) => if err @logSubscriptionError(user, 'Stripe user plan saving error. ' + err) @@ -551,11 +553,11 @@ class SubscriptionHandler extends Handler @logSubscriptionError(user, 'Stripe user saving stripe error. ' + err) return done({res: 'Database error.', code: 500}) done() - + tasks = [] for sub in stripeRecipients tasks.push createUpdateFn(sub.recipient, sub.increment) - + async.parallel tasks, (err, results) => return done(err) if err @updateStripeSponsorSubscription(req, user, customer, product, done) @@ -673,13 +675,13 @@ class SubscriptionHandler extends Handler if err @logSubscriptionError(user, 'Recipient user save unsubscribe error. ' + err) return done({res: 'Database error.', code: 500}) - + # Cancel Stripe subscription stripe.customers.cancelSubscription stripeInfo.customerID, sponsoredEntry.subscriptionID, (err) => if err @logSubscriptionError(user, "Stripe cancel sponsored subscription failed. " + err) return done({res: 'Database error.', code: 500}) - + # Update sponsor user _.remove(stripeInfo.recipients, (s) -> s.userID is recipient.id) delete stripeInfo.unsubscribeEmail @@ -689,9 +691,9 @@ class SubscriptionHandler extends Handler if err @logSubscriptionError(user, 'Sponsor user save unsubscribe error. ' + err) return done({res: 'Database error.', code: 500}) - + return done() unless stripeInfo.sponsorSubscriptionID? - + # Update sponsored subscription quantity options = quantity: getSponsoredSubsAmount(product.get('amount'), stripeInfo.recipients.length, stripeInfo.subscriptionID?) diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index d70090c45..e425418de 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -198,7 +198,7 @@ module.exports.loginUser = loginUser = (req, res, user, send=true, next=null) -> ) module.exports.idCounter = 0 - + module.exports.makeNewUser = makeNewUser = (req) -> user = new User({anonymous: true}) if global.testing diff --git a/server/routes/stripe.coffee b/server/routes/stripe.coffee index 27330411e..a8c965492 100644 --- a/server/routes/stripe.coffee +++ b/server/routes/stripe.coffee @@ -85,7 +85,11 @@ module.exports.setup = (app) -> subscriptionID: subscriptionID } }) - payment.set 'gems', 3500 if invoice.lines.data[0].plan?.id is 'basic' + # TODO: load gems from correct Product + productGems = 3500 + if recipient.get('country') is 'brazil' + productGems = 1500 + payment.set 'gems', productGems if invoice.lines.data[0].plan?.id is 'basic' payment.save (err) => if err From 67f7ce1e0d836ccef7b4e998d0006fbee12a3ea8 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 12 Jan 2016 12:25:13 -0800 Subject: [PATCH 2/2] Add Brazil coupon test. Generalize prices in subscription test a bit more. Handle brazil_basic_subscription product in one more place. --- server/payments/subscription_handler.coffee | 8 +- server/routes/db/product.coffee | 11 +- server/routes/stripe.coffee | 3 +- spec/fixtures/sub-test-41.json | 362 ++++++++++++++++++ .../functional/subscription.spec.coffee | 111 ++++-- 5 files changed, 457 insertions(+), 38 deletions(-) create mode 100644 spec/fixtures/sub-test-41.json diff --git a/server/payments/subscription_handler.coffee b/server/payments/subscription_handler.coffee index 0fb7b191e..de351c550 100644 --- a/server/payments/subscription_handler.coffee +++ b/server/payments/subscription_handler.coffee @@ -428,7 +428,11 @@ class SubscriptionHandler extends Handler req.body.stripe = stripeInfo user.set('stripe', stripeInfo) - Product.findOne({name: 'basic_subscription'}).exec (err, product) => + productName = 'basic_subscription' + if user.get('country') in ['brazil'] + productName = "#{user.get('country')}_basic_subscription" + + Product.findOne({name: productName}).exec (err, product) => return @sendDatabaseError(res, err) if err return @sendNotFoundError(res, 'basic_subscription product not found') if not product @@ -436,7 +440,7 @@ class SubscriptionHandler extends Handler purchased = _.clone(user.get('purchased')) purchased ?= {} purchased.gems ?= 0 - purchased.gems += product.get('gems') # TODO: Put actual subscription amount here + purchased.gems += product.get('gems') user.set('purchased', purchased) user.save (err) => diff --git a/server/routes/db/product.coffee b/server/routes/db/product.coffee index eefd89e11..c1b854aea 100644 --- a/server/routes/db/product.coffee +++ b/server/routes/db/product.coffee @@ -17,7 +17,7 @@ module.exports.get = (req, res) -> ### Stub data, used in tests and dev environment. - + These values are only upserted when the test/dev db does not already contain them. If you are testing products and need to change them, you'll need to edit the db values directly. ### @@ -76,4 +76,11 @@ initProducts = [ name: 'course' amount: 100 } -] \ No newline at end of file + + { + name: 'brazil_basic_subscription' + amount: 0 + gems: 1500 + planID: 'basic' + } +] diff --git a/server/routes/stripe.coffee b/server/routes/stripe.coffee index a8c965492..1541ca672 100644 --- a/server/routes/stripe.coffee +++ b/server/routes/stripe.coffee @@ -49,8 +49,9 @@ module.exports.setup = (app) -> if err logStripeWebhookError("Retrieve invoice error: #{JSON.stringify(err)}") return res.send(500, '') - unless invoice.total or invoice.discount?.coupon?.id is 'free' + unless invoice.total or invoice.discount?.coupon?.id in ['free', 'brazil'] # invoices made when trialing, probably given for people who resubscribe after unsubscribing + # also I can't change the test-mode brazil coupon to not end up with a zero price now return res.send(200, '') return res.send(200, '') unless invoice.lines?.data?.length > 0 diff --git a/spec/fixtures/sub-test-41.json b/spec/fixtures/sub-test-41.json new file mode 100644 index 000000000..a1ffde3b4 --- /dev/null +++ b/spec/fixtures/sub-test-41.json @@ -0,0 +1,362 @@ +[ + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/tokens", + "status": 200, + "response": { + "id": "tok_17SYfcKaReE7xLUdYjNZZzl4", + "card": { + "id": "card_17SYfcKaReE7xLUdQAQATTm4" + }, + "type": "card" + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/customers", + "status": 200, + "response": { + "id": "cus_7hyc7Vrhs9hrFd", + "alipay_accounts": { + "has_more": false + }, + "email": "user219@me.com", + "metadata": { + "id": "0000000000000000000186e5" + }, + "sources": { + "data": [ + { + "id": "card_17SYfcKaReE7xLUdQAQATTm4", + "customer": "cus_7hyc7Vrhs9hrFd" + } + ], + "has_more": false + }, + "subscriptions": { + "has_more": false + } + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/customers/cus_7hyc7Vrhs9hrFd/subscriptions", + "status": 200, + "response": { + "id": "sub_7hycAhun9MsBGL", + "cancel_at_period_end": false, + "current_period_end": 1455308593, + "current_period_start": 1452630193, + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "quantity": 1 + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/customers/cus_7hyc7Vrhs9hrFd", + "status": 200, + "response": { + "id": "cus_7hyc7Vrhs9hrFd", + "alipay_accounts": { + "has_more": false + }, + "email": "user219@me.com", + "metadata": { + "id": "0000000000000000000186e5" + }, + "sources": { + "data": [ + { + "id": "card_17SYfcKaReE7xLUdQAQATTm4", + "customer": "cus_7hyc7Vrhs9hrFd" + } + ], + "has_more": false + }, + "subscriptions": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "cancel_at_period_end": false, + "current_period_end": 1455308593, + "current_period_start": 1452630193, + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "quantity": 1 + } + ], + "has_more": false + } + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "GET", + "path": "/v1/invoices", + "status": 200, + "response": { + "data": [ + { + "id": "in_17SYfdKaReE7xLUdVctB1XaE", + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "lines": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "amount": 100, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "proration": false, + "quantity": 1, + "type": "subscription" + } + ], + "has_more": false + }, + "paid": true, + "subscription": "sub_7hycAhun9MsBGL", + "total": 0 + } + ], + "has_more": false + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/customers/cus_7hyc7Vrhs9hrFd", + "status": 200, + "response": { + "id": "cus_7hyc7Vrhs9hrFd", + "alipay_accounts": { + "has_more": false + }, + "email": "user219@me.com", + "metadata": { + "id": "0000000000000000000186e5" + }, + "sources": { + "data": [ + { + "id": "card_17SYfcKaReE7xLUdQAQATTm4", + "customer": "cus_7hyc7Vrhs9hrFd" + } + ], + "has_more": false + }, + "subscriptions": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "cancel_at_period_end": false, + "current_period_end": 1455308593, + "current_period_start": 1452630193, + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "quantity": 1 + } + ], + "has_more": false + } + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "POST", + "path": "/v1/customers/cus_7hyc7Vrhs9hrFd", + "status": 200, + "response": { + "id": "cus_7hyc7Vrhs9hrFd", + "alipay_accounts": { + "has_more": false + }, + "email": "user219@me.com", + "metadata": { + "id": "0000000000000000000186e5" + }, + "sources": { + "data": [ + { + "id": "card_17SYfcKaReE7xLUdQAQATTm4", + "customer": "cus_7hyc7Vrhs9hrFd" + } + ], + "has_more": false + }, + "subscriptions": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "cancel_at_period_end": false, + "current_period_end": 1455308593, + "current_period_start": 1452630193, + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "quantity": 1 + } + ], + "has_more": false + } + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "GET", + "path": "/v1/invoices/in_17SYfdKaReE7xLUdVctB1XaE", + "status": 200, + "response": { + "id": "in_17SYfdKaReE7xLUdVctB1XaE", + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "lines": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "amount": 100, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "proration": false, + "quantity": 1, + "type": "subscription" + } + ], + "has_more": false + }, + "paid": true, + "subscription": "sub_7hycAhun9MsBGL", + "total": 0 + } + }, + { + "scope": "https://api.stripe.com:443", + "method": "GET", + "path": "/v1/customers/cus_7hyc7Vrhs9hrFd", + "status": 200, + "response": { + "id": "cus_7hyc7Vrhs9hrFd", + "alipay_accounts": { + "has_more": false + }, + "email": "user219@me.com", + "metadata": { + "id": "0000000000000000000186e5" + }, + "sources": { + "data": [ + { + "id": "card_17SYfcKaReE7xLUdQAQATTm4", + "customer": "cus_7hyc7Vrhs9hrFd" + } + ], + "has_more": false + }, + "subscriptions": { + "data": [ + { + "id": "sub_7hycAhun9MsBGL", + "cancel_at_period_end": false, + "current_period_end": 1455308593, + "current_period_start": 1452630193, + "customer": "cus_7hyc7Vrhs9hrFd", + "discount": { + "coupon": { + "id": "brazil" + }, + "customer": "cus_7hyc7Vrhs9hrFd", + "subscription": "sub_7hycAhun9MsBGL" + }, + "metadata": { + "id": "0000000000000000000186e5" + }, + "plan": { + "id": "basic", + "amount": 100 + }, + "quantity": 1 + } + ], + "has_more": false + } + } + } +] \ No newline at end of file diff --git a/spec/server/functional/subscription.spec.coffee b/spec/server/functional/subscription.spec.coffee index fe8fa5143..44b562665 100644 --- a/spec/server/functional/subscription.spec.coffee +++ b/spec/server/functional/subscription.spec.coffee @@ -6,6 +6,9 @@ mongoose = require 'mongoose' TRAVIS = process.env.COCO_TRAVIS_TEST nockUtils = require '../nock-utils' +subPrice = 100 +subGems = 3500 +subGemsBrazil = 1500 # sample data that comes in through the webhook when you subscribe invoiceChargeSampleEvent = { @@ -143,7 +146,7 @@ describe '/db/user, editing stripe property', -> request.put {uri: userURL, json: joeData, headers: headers }, (err, res, body) -> joeData = body expect(res.statusCode).toBe(200) - expect(joeData.purchased.gems).toBe(3500) + expect(joeData.purchased.gems).toBe(subGems) expect(joeData.stripe.customerID).toBeDefined() expect(firstSubscriptionID = joeData.stripe.subscriptionID).toBeDefined() expect(joeData.stripe.planID).toBe('basic') @@ -158,13 +161,13 @@ describe '/db/user, editing stripe property', -> expect(invoices.data.length).toBe(1) event = _.cloneDeep(invoiceChargeSampleEvent) event.data.object = invoices.data[0] - + request.post {uri: webhookURL, json: event}, (err, res, body) -> expect(res.statusCode).toBe(201) Payment.find {}, (err, payments) -> expect(payments.length).toBe(1) User.findById joeData._id, (err, user) -> - expect(user.get('purchased').gems).toBe(3500) + expect(user.get('purchased').gems).toBe(subGems) nockDone() done() @@ -188,7 +191,7 @@ describe '/db/user, editing stripe property', -> joeData.stripe.planID = 'basic' request.put {uri: userURL, json: joeData, headers: headers }, (err, res, body) -> joeData = body - + expect(res.statusCode).toBe(200) expect(joeData.stripe.customerID).toBeDefined() expect(joeData.stripe.subscriptionID).toBeDefined() @@ -204,13 +207,13 @@ describe '/db/user, editing stripe property', -> expect(invoices.data[0].total).toBe(0) event = _.cloneDeep(invoiceChargeSampleEvent) event.data.object = invoices.data[0] - + request.post {uri: webhookURL, json: event}, (err, res, body) -> expect(res.statusCode).toBe(200) Payment.find {}, (err, payments) -> expect(payments.length).toBe(1) User.findById joeData._id, (err, user) -> - expect(user.get('purchased').gems).toBe(3500) + expect(user.get('purchased').gems).toBe(subGems) nockDone() done() @@ -221,7 +224,7 @@ describe '/db/user, editing stripe property', -> event.data.object = subscription request.post {uri: webhookURL, json: event}, (err, res, body) -> User.findById joeData._id, (err, user) -> - expect(user.get('purchased').gems).toBe(3500) + expect(user.get('purchased').gems).toBe(subGems) expect(user.get('stripe').subscriptionID).toBeUndefined() expect(user.get('stripe').planID).toBeUndefined() nockDone() @@ -246,8 +249,6 @@ describe 'Subscriptions', -> userURL = getURL('/db/user') webhookURL = getURL('/stripe/webhook') headers = {'X-Change-Plan': 'true'} - subPrice = 100 - subGems = 3500 invoicesWebHooked = {} afterEach nockUtils.teardownNock @@ -620,7 +621,7 @@ describe 'Subscriptions', -> expect(stripeInfo.prepaidCode).toEqual(prepaid.get('code')) expect(stripeInfo.subscriptionID).toBeDefined() return done() unless stripeInfo.subscriptionID - + # Delete subscription stripe.customers.retrieveSubscription stripeInfo.customerID, stripeInfo.subscriptionID, (err, subscription) -> expect(err).toBeNull() @@ -843,7 +844,7 @@ describe 'Subscriptions', -> nockDone() done() - + it 'Recipient user delete unsubscribes', (done) -> nockUtils.setupNock 'sub-test-14.json', (err, nockDone) -> stripe.tokens.create { @@ -942,7 +943,7 @@ describe 'Subscriptions', -> verifyNotRecipient user2.id, -> nockDone() done() - + it 'Unsubscribed user1 immediately resubscribes user2, one token', (done) -> nockUtils.setupNock 'sub-test-18.json', (err, nockDone) -> @@ -1318,25 +1319,25 @@ describe 'Subscriptions', -> recipientCount = 2 recipientsToVerify = [0, 1] recipients = new SubbedRecipients recipientCount, recipientsToVerify - + # Create recipients recipients.createRecipients -> expect(recipients.length()).toEqual(recipientCount) - + stripe.tokens.create { card: { number: '4242424242424242', exp_month: 12, exp_year: 2020, cvc: '123' } }, (err, token) -> - + # Create sponsor user loginNewUser (user1) -> subscribeUser user1, token, null, (updatedUser) -> User.findById user1.id, (err, user1) -> expect(err).toBeNull() - + # Subscribe recipients recipients.subRecipients user1, null, -> User.findById user1.id, (err, user1) -> - + # Unsubscribe recipient0 unsubscribeRecipient user1, recipients.get(0), -> User.findById user1.id, (err, user1) -> @@ -1348,7 +1349,7 @@ describe 'Subscriptions', -> expect(err).toBeNull() expect(subscription).not.toBeNull() expect(subscription?.quantity).toEqual(getSubscribedQuantity(1)) - + # Unsubscribe recipient1 unsubscribeRecipient user1, recipients.get(1), -> User.findById user1.id, (err, user1) -> @@ -1519,11 +1520,11 @@ describe 'Subscriptions', -> endDate.setUTCFullYear(endDate.getUTCFullYear() + 1) expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10)) expect(stripeInfo.customerID).toBeDefined() - expect(user1.get('purchased')?.gems).toEqual(3500*12) + expect(user1.get('purchased')?.gems).toEqual(subGems*12) Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) -> expect(err).toBeNull() - expect(payment).toBeDefined() - expect(payment.get('gems')).toEqual(3500*12) + expect(payment).toBeTruthy() + expect(payment.get('gems')).toEqual(subGems*12) nockDone() done() @@ -1553,11 +1554,11 @@ describe 'Subscriptions', -> endDate.setUTCFullYear(endDate.getUTCFullYear() + 1) expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10)) expect(stripeInfo.customerID).toBeDefined() - expect(user1.get('purchased')?.gems).toEqual(3500*12) + expect(user1.get('purchased')?.gems).toEqual(subGems*12) Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) -> expect(err).toBeNull() - expect(payment).toBeDefined() - expect(payment.get('gems')).toEqual(3500*12) + expect(payment).toBeTruthy() + expect(payment.get('gems')).toEqual(subGems*12) nockDone() done() @@ -1589,11 +1590,11 @@ describe 'Subscriptions', -> endDate.setUTCFullYear(endDate.getUTCFullYear() + 1) expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10)) expect(stripeInfo.customerID).toBeDefined() - expect(user1.get('purchased')?.gems).toEqual(3500*12) + expect(user1.get('purchased')?.gems).toEqual(subGems*12) Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) -> expect(err).toBeNull() - expect(payment).toBeDefined() - expect(payment.get('gems')).toEqual(3500*12) + expect(payment).toBeTruthy() + expect(payment.get('gems')).toEqual(subGems*12) nockDone() done() @@ -1626,11 +1627,11 @@ describe 'Subscriptions', -> endDate.setUTCDate(endDate.getUTCDate() + 5) expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10)) expect(stripeInfo.customerID).toBeDefined() - expect(user1.get('purchased')?.gems).toEqual(3500*12) + expect(user1.get('purchased')?.gems).toEqual(subGems*12) Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) -> expect(err).toBeNull() - expect(payment).toBeDefined() - expect(payment.get('gems')).toEqual(3500*12) + expect(payment).toBeTruthy() + expect(payment.get('gems')).toEqual(subGems*12) nockDone() done() @@ -1667,11 +1668,11 @@ describe 'Subscriptions', -> endDate.setUTCFullYear(endDate.getUTCFullYear() + 1) expect(stripeInfo.free).toEqual(endDate.toISOString().substring(0, 10)) expect(stripeInfo.customerID).toBeDefined() - expect(user1.get('purchased')?.gems).toEqual(3500+3500*12) + expect(user1.get('purchased')?.gems).toEqual(subGems+subGems*12) Payment.findOne 'stripe.customerID': stripeInfo.customerID, (err, payment) -> expect(err).toBeNull() - expect(payment).toBeDefined() - expect(payment.get('gems')).toEqual(3500*12) + expect(payment).toBeTruthy() + expect(payment.get('gems')).toEqual(subGems*12) nockDone() done() @@ -1693,3 +1694,47 @@ describe 'Subscriptions', -> expect(err).toBeNull() nockDone() done() + + describe 'Countries', -> + it 'Brazil users get Brazil coupon', (done) -> + nockUtils.setupNock 'sub-test-41.json', (err, nockDone) -> + stripe.tokens.create { + card: { number: '4242424242424242', exp_month: 12, exp_year: 2030, cvc: '123' } + }, (err, token) -> + loginNewUser (user1) -> + user1.set('country', 'brazil') + user1.save (err, user1) -> + requestBody = user1.toObject() + requestBody.stripe = + planID: 'basic' + token: token.id + request.put {uri: userURL, json: requestBody, headers: headers }, (err, res, updatedUser) -> + expect(err).toBeNull() + expect(res.statusCode).toBe(200) + expect(updatedUser.country).toBe('brazil') + expect(updatedUser.purchased.gems).toBe(subGemsBrazil) + expect(updatedUser.stripe.planID).toBe('basic') + expect(updatedUser.stripe.customerID).toBeTruthy() + + stripe.invoices.list {customer: updatedUser.stripe.customerID}, (err, invoices) -> + expect(err).toBeNull() + expect(invoices).not.toBeNull() + expect(invoices.data.length).toBe(1) + expect(invoices.data[0].discount?.coupon).toBeTruthy() + expect(invoices.data[0].discount?.coupon?.id).toBe('brazil') + expect(invoices.data[0].total).toBeLessThan(subPrice) + + # Now we hit our webhook to see if the right Payment is made. + event = _.cloneDeep(invoiceChargeSampleEvent) + event.data.object = invoices.data[0] + request.post {uri: webhookURL, json: event}, (err, res, body) -> + expect(err).toBeNull() + expect(res.statusCode).toBe(201) + Payment.findOne 'stripe.customerID': updatedUser.stripe.customerID, (err, payment) -> + expect(err).toBeNull() + expect(payment).toBeTruthy() + return done() unless payment + expect(payment.get('gems')).toEqual(subGemsBrazil) + expect(payment.get('amount')).toBeLessThan(subPrice) + nockDone() + done()