Files
habitica/website/server/controllers/top-level/payments/iap.js
Phillip Thelen cfbfec34aa Allow gems and subs to be gifted through in-app-purchases (#10892)
* Allow gems to be gifted through IAPs

* implement non recurring IAP subscriptions

* fix localization issue in error

* fix non renewing subscription handling

* Fix lint error

* fix tests

* move findbyId mock to helper file

* undo package-lock changes

* Fix lint error
2018-12-23 19:20:14 +01:00

196 lines
5.3 KiB
JavaScript

import {
authWithHeaders,
} from '../../../middlewares/auth';
import {
BadRequest,
} from '../../../libs/errors';
import googlePayments from '../../../libs/payments/google';
import applePayments from '../../../libs/payments/apple';
let api = {};
// TODO missing tests
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/android/verify Android Verify IAP
* @apiName IapAndroidVerify
* @apiGroup Payments
**/
api.iapAndroidVerify = {
method: 'POST',
url: '/iap/android/verify',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.transaction) throw new BadRequest(res.t('missingReceipt'));
let googleRes = await googlePayments.verifyGemPurchase({
user: res.locals.user,
receipt: req.body.transaction.receipt,
signature: req.body.transaction.signature,
gift: req.body.gift,
headers: req.headers,
});
res.respond(200, googleRes);
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/android/subscription Android Subscribe
* @apiName IapAndroidSubscribe
* @apiGroup Payments
**/
api.iapSubscriptionAndroid = {
method: 'POST',
url: '/iap/android/subscribe',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.sku) throw new BadRequest(res.t('missingSubscriptionCode'));
await googlePayments.subscribe(req.body.sku, res.locals.user, req.body.transaction.receipt, req.body.transaction.signature, req.headers);
res.respond(200);
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/android/norenew-subscribe Android non-renewing subscription IAP
* @apiName iapSubscriptionAndroidNoRenew
* @apiGroup Payments
**/
api.iapSubscriptionAndroidNoRenew = {
method: 'POST',
url: '/iap/android/norenew-subscribe',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.sku) throw new BadRequest(res.t('missingSubscriptionCode'));
if (!req.body.transaction) throw new BadRequest(res.t('missingReceipt'));
await googlePayments.noRenewSubscribe({
sku: req.body.sku,
user: res.locals.user,
receipt: req.body.transaction.receipt,
signature: req.body.transaction.signature,
gift: req.body.gift,
headers: req.headers,
});
res.respond(200);
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {get} /iap/android/subscribe/cancel Google Payments: subscribe cancel
* @apiName AndroidSubscribeCancel
* @apiGroup Payments
**/
api.iapCancelSubscriptionAndroid = {
method: 'GET',
url: '/iap/android/subscribe/cancel',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
await googlePayments.cancelSubscribe(user, req.headers);
if (req.query.noRedirect) {
res.respond(200);
} else {
res.redirect('/');
}
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/ios/verify iOS Verify IAP
* @apiName IapiOSVerify
* @apiGroup Payments
**/
api.iapiOSVerify = {
method: 'POST',
url: '/iap/ios/verify',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.transaction) throw new BadRequest(res.t('missingReceipt'));
let appleRes = await applePayments.verifyGemPurchase({
user: res.locals.user,
receipt: req.body.transaction.receipt,
gift: req.body.gift,
headers: req.headers,
});
res.respond(200, appleRes);
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/android/subscription iOS Subscribe
* @apiName IapiOSSubscribe
* @apiGroup Payments
**/
api.iapSubscriptioniOS = {
method: 'POST',
url: '/iap/ios/subscribe',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.sku) throw new BadRequest(res.t('missingSubscriptionCode'));
if (!req.body.receipt) throw new BadRequest(res.t('missingReceipt'));
await applePayments.subscribe(req.body.sku, res.locals.user, req.body.receipt, req.headers);
res.respond(200);
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {get} /iap/android/subscribe/cancel Apple Payments: subscribe cancel
* @apiName iOSSubscribeCancel
* @apiGroup Payments
**/
api.iapCancelSubscriptioniOS = {
method: 'GET',
url: '/iap/ios/subscribe/cancel',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
await applePayments.cancelSubscribe(user, req.headers);
if (req.query.noRedirect) {
res.respond(200);
} else {
res.redirect('/');
}
},
};
/**
* @apiIgnore Payments are considered part of the private API
* @api {post} /iap/ios/norenew-subscribe iOS Verify IAP
* @apiName IapiOSVerify
* @apiGroup Payments
**/
api.iapSubscriptioniOSNoRenew = {
method: 'POST',
url: '/iap/ios/norenew-subscribe',
middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.sku) throw new BadRequest(res.t('missingSubscriptionCode'));
if (!req.body.transaction) throw new BadRequest(res.t('missingReceipt'));
await applePayments.noRenewSubscribe({
sku: req.body.sku,
user: res.locals.user,
receipt: req.body.transaction.receipt,
gift: req.body.gift,
headers: req.headers});
res.respond(200);
},
};
module.exports = api;