Merge branch 'master' into production

This commit is contained in:
Nick Winter 2016-01-12 12:29:04 -08:00
commit 014d688b08
64 changed files with 617 additions and 187 deletions

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 силни <strong>нови герои</strong> с уникални умения!"
feature3: "70+ бонус нива" # {change}
feature4: "<strong>3500 скъпоценни камъни бонус</strong> всеки месец!"
feature4: "<strong>{{gems}} скъпоценни камъни бонус</strong> всеки месец!"
feature5: "Видео уроци"
feature6: "Премиум email поддръжка"
feature7: "Частни <strong>Кланове</strong>"

View file

@ -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 <strong>nous herois</strong> poderosos amb habilitats úniques!"
feature3: "Més de 80 nivells bonus"
feature4: "<strong>3500 gemmes bonus</strong> cada mes!"
feature4: "<strong>{{gems}} gemmes bonus</strong> cada mes!"
feature5: "Vídeo tutorials"
feature6: "Suport Premium per correu electrònic"
feature7: "Privat <strong>Clans</strong>"

View file

@ -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 <strong>nových hrdinů</strong> s jedinečnými dovednostmi!" # {change}
feature3: "30+ bonusových úrovní" # {change}
feature4: "<strong>3500 bonusových drahokamů</strong> každý měsíc!"
feature4: "<strong>{{gems}} bonusových drahokamů</strong> každý měsíc!"
feature5: "Video tutoriály"
feature6: "Premiová e-mailová podpora"
feature7: "Soukromé <strong>Klany</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
feature3: "50+ bonus levels" # {change}
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
feature5: "Video Aleitige"
feature6: "Premium Email Hilf"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>neue Helden</strong> mit einzigartigen Fertigkeiten" # {change}
feature3: "30+ Bonuslevel" # {change}
feature4: "<strong>3500 Bonusedelsteine</strong> jeden Monat!"
feature4: "<strong>{{gems}} Bonusedelsteine</strong> jeden Monat!"
feature5: "Videoanleitungen"
feature6: "Premium Emailsupport"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 παντοδύναμοι <strong>νέοι ήρωες</strong> με μοναδικές ικανότητες!"
feature3: "80+ επίπεδα δώρο"
feature4: "<strong>3500 πετράδια δώρο</strong> κάθε μήνα!"
feature4: "<strong>{{gems}} πετράδια δώρο</strong> κάθε μήνα!"
feature5: "Βίντεο Βοηθήματα"
feature6: "Προνομιακή υποστήριξη μέσω ηλεκτρονικού ταχυδρομείου"
feature7: "Ιδιωτικές <strong>Φατρίες</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
feature3: "80+ bonus levels"
feature4: "<strong>3500 bonus gems</strong> every month!"
feature4: "<strong>{{gems}} bonus gems</strong> every month!"
feature5: "Video tutorials"
feature6: "Premium email support"
feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>nuevos heroés</strong> con habilidades unicas!"
feature3: "Más de 70 niveles extras" # {change}
feature4: "<strong>3500 gemas de bono</strong> cada mes!"
feature4: "<strong>{{gems}} gemas de bono</strong> cada mes!"
feature5: "Video tutoriales"
feature6: "Soporte Premium vía email"
feature7: "<strong>Clan</strong> Privado"

View file

@ -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 <strong>héroes nuevos</strong> con poderes únicos!"
feature3: "Más de 70 niveles extra" # {change}
feature4: "¡<strong>3500 gemas extra</strong> cada mes!"
feature4: "¡<strong>{{gems}} gemas extra</strong> cada mes!"
feature5: "Vídeo tutoriales"
feature6: "Soporte electrónico Premium"
feature7: "<strong>Clanes</strong> privados"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>uutta sankaria</strong> erilaisine kykyineen!"
feature3: "70+ lisätasoa" # {change}
feature4: "<strong>3500 jalokiveä</strong> joka kuukausi!"
feature4: "<strong>{{gems}} jalokiveä</strong> joka kuukausi!"
feature5: "Video-oppaat"
feature6: "Premium sähköpostituki"
feature7: "<strong>Yksityisklaanit</strong>"

View file

@ -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 <strong>nouveaux héros</strong> avec des compétences uniques !" # {change}
feature3: "Plus de 30 niveaux bonus" # {change}
feature4: "<strong>3500 gemmes bonus</strong> tous les mois !"
feature4: "<strong>{{gems}} gemmes bonus</strong> tous les mois !"
feature5: "Tutoriels vidéo"
feature6: "Assitance par e-mail dédiée"
feature7: "<strong>Clans</strong> privés"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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: "!עם כישורים מיוחדים <strong>גיבורים עוצמתיים חדשים</strong> 7" # {change}
feature3: "30+ שלבי בונוס" # {change}
feature4: "!בחינם כל חודש <strong>3500 אבני חן</strong>"
feature4: "!בחינם כל חודש <strong>{{gems}} אבני חן</strong>"
feature5: "הדרכות וידאו"
feature6: "תמיכת מייל בעדיפות ראשונה"
feature7: "פרטיים <strong>שבטים</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>új hős</strong> egyedi képességekkel!" # {change}
feature3: "30+ bónusz pálya" # {change}
feature4: "<strong>3500 bónusz drágakő</strong> minden hónapban!"
feature4: "<strong>{{gems}} bónusz drágakő</strong> minden hónapban!"
feature5: "Videó oktatóanyagok"
feature6: "Prémium email támogatás"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>nuovi eroi</strong> con capacità uniche!" # {change}
feature3: "50+ livelli bonus" # {change}
feature4: "<strong>3500 gemme bonus</strong> ogni mese!"
feature4: "<strong>{{gems}} gemme bonus</strong> ogni mese!"
feature5: "Video tutorial"
feature6: "Supporto via email premium"
feature7: "Clan <strong>privati</strong>"

View file

@ -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以上の基本レベルがつの世界に" # {change}
feature2: "10人のパワフルな <strong>ニューヒーロー</strong> とユニークなスキル!" # {change}
feature3: "70以上のボーナスレベル" # {change}
feature4: "<strong>3500のジェム</strong>が毎月ボーナス!"
feature4: "<strong>{{gems}}のジェム</strong>が毎月ボーナス!"
feature5: "ビデオチュートリアル"
feature6: "プレミアムメールサポート"
feature7: "プライベート<strong>クラン</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>nye helter</strong> med unike ferdigheter!" # {change}
feature3: "30+ bonusbrett" # {change}
feature4: "<strong>3500 bonusjuveler</strong> hver måned!"
feature4: "<strong>{{gems}} bonusjuveler</strong> hver måned!"
feature5: "Videoveiledninger"
feature6: "Premium e-poststøtte"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>nieuwe helden</strong> met unieke vaardigheden!"
feature3: "70+ bonuslevels" # {change}
feature4: "<strong>3500 bonus edelstenen</strong> elke maand!"
feature4: "<strong>{{gems}} bonus edelstenen</strong> elke maand!"
feature5: "Video cursussen"
feature6: "Hoogwaardige e-mail ondersteuning"
feature7: "Besloten <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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, <strong>nowych bohaterów</strong> z unikalnymi umiejętnościami!" # {change}
feature3: "Ponad 70 bonusowych poziomów" # {change}
feature4: "Dodatkowe <strong>3500 klejnotów</strong> co miesiąc!"
feature4: "Dodatkowe <strong>{{gems}} klejnotów</strong> co miesiąc!"
feature5: "Poradniki wideo"
feature6: "Priorytetowe wsparcie przez e-mail"
feature7: "Prywatne <strong>Klany</strong>"

View file

@ -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 <strong>novos heróis</strong> com habilidades únicas!" # {change}
feature3: "Mais de 30 níveis bônus" # {change}
feature4: "<strong>3500 gemas bônus</strong> todo mês!"
feature4: "<strong>{{gems}} gemas bônus</strong> todo mês!"
feature5: "Vídeo tutorials"
feature6: "Suporte via e-mail Premium"
feature7: "<strong>Clãs</strong> Privados"

View file

@ -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 <strong>heróis novos</strong> e poderosos com habilidades únicas!"
feature3: "80+ níveis de bónus"
feature4: "<strong>3500 gemas de bónus</strong> por mês!"
feature4: "<strong>{{gems}} gemas de bónus</strong> por mês!"
feature5: "Tutoriais em vídeo"
feature6: "Apoio por e-mail prioritário"
feature7: "<strong>Clãs</strong> Privados"

View file

@ -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 <strong>Eroi Noi</strong> puternici, cu skilluri unice!" # {change}
feature3: "60+ nivele bonus" # {change}
feature4: "<strong>3500 de Pietre Prețioase bonus</strong> în fiecare lună!"
feature4: "<strong>{{gems}} de Pietre Prețioase bonus</strong> în fiecare lună!"
feature5: "Tutoriale Video"
feature6: "Suport e-mail premium"
feature7: "<strong>Clanuri</strong> private"

View file

@ -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 могущественных <strong>новых героев</strong> с уникальными способностями!" # {change}
feature3: "60+ дополнительных уровней" # {change}
feature4: "<strong>3500 бонусных самоцветов</strong> каждый месяц!"
feature4: "<strong>{{gems}} бонусных самоцветов</strong> каждый месяц!"
feature5: "Обучающие видеоролики"
feature6: "Эксклюзивная поддержка по электронной почте"
feature7: "Частные <strong>Кланы</strong>"

View file

@ -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 <strong>new hrdinov</strong> s jedinečnými schopnosťami!" # {change}
feature3: "30+ bonusových úrovní" # {change}
feature4: "<strong>3500 bonusových diamantov</strong> každý mesiac !"
feature4: "<strong>{{gems}} bonusových diamantov</strong> každý mesiac !"
feature5: "Video tutoriály"
feature6: "Prémiová emailová podpora"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 могутніх <strong>нових героїв</strong> з унікальними здібностями!"
feature3: "Більше 80-ти бонусних рівнів"
feature4: "<strong>3500 бонусних самоцвітів</strong> кожного місяця!"
feature4: "<strong>{{gems}} бонусних самоцвітів</strong> кожного місяця!"
feature5: "Навчальні відеоролики"
feature6: "Екслюзивна підтримка по електронній пошті"
feature7: "Приватні <strong>клани</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>nhât vật mới</strong> mạnh mẽ với những kĩ năng đặc biệt!" # {change}
# feature3: "80+ bonus levels"
feature4: "<strong>Được thưởng thêm 3500 ngọc</strong> mỗi tháng!"
feature4: "<strong>Được thưởng thêm {{gems}} ngọc</strong> 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 <strong>Clans</strong>"

View file

@ -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 个强大 <strong>英雄</strong>以及各式非凡技能!"
feature3: "80+ 奖励关卡"
feature4: "每月享有3500额外宝石"
feature4: "每月享有{{gems}}额外宝石"
feature5: "视频教学"
feature6: "专业邮件支援"
feature7: "私人 <strong>部落</strong>"

View file

@ -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 個強壯的<strong>新英雄</strong>並每位都有不同技巧!"
feature3: "80 個以上的額外關卡"
feature4: "每個月<strong>3500顆額外寶石</strong>"
feature4: "每個月<strong>{{gems}}顆額外寶石</strong>"
feature5: "影片教學"
feature6: "頂級信箱支援"
feature7: "私密<strong>部落</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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 <strong>new heroes</strong> with unique skills!"
# feature3: "80+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!"
# feature4: "<strong>{{gems}} bonus gems</strong> every month!"
# feature5: "Video tutorials"
# feature6: "Premium email support"
# feature7: "Private <strong>Clans</strong>"

View file

@ -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'

View file

@ -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

View file

@ -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 = "<p>" + $.i18n.t('subscribe.parents_blurb1', nLevels: levelsCompleted) + "</p>"
popoverContent += "<p>" + $.i18n.t('subscribe.parents_blurb1a') + "</p>"
popoverContent += "<p>" + $.i18n.t('subscribe.parents_blurb2') + "</p>"
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 += "<p>" + $.i18n.t('subscribe.parents_blurb3') + "</p>"
@ -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 += '<button type="button" class="close" onclick="$(&#39;#payment-methods-info&#39;).popover(&#39;hide&#39;);">&times;</button>'
popoverContent = "<p>" + $.i18n.t('subscribe.payment_methods_blurb1') + "</p>"
# 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 += "<p>" + $.i18n.t('subscribe.payment_methods_blurb2') + " <a href='mailto:support@codecombat.com'>support@codecombat.com</a>."
@$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') ? {}

View file

@ -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()

View file

@ -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
@ -426,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
@ -434,9 +440,9 @@ 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) =>
if err
@logSubscriptionError(user, 'Stripe user plan saving error. ' + err)
@ -551,11 +557,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 +679,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 +695,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?)

View file

@ -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

View file

@ -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
}
]
{
name: 'brazil_basic_subscription'
amount: 0
gems: 1500
planID: 'basic'
}
]

View file

@ -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
@ -85,7 +86,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

362
spec/fixtures/sub-test-41.json vendored Normal file
View file

@ -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
}
}
}
]

View file

@ -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()