Compare commits
7 Commits
develop
...
qa/starfish
| Author | SHA1 | Date | |
|---|---|---|---|
| 835706cd81 | |||
| 2baca238b2 | |||
| 3915b04aed | |||
| 763adbdf8b | |||
| 2f74e0e8e7 | |||
| 729c8bc72b | |||
| c0d812ad8d |
@@ -236,8 +236,9 @@ describe('Google Payments', () => {
|
||||
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
|
||||
sub,
|
||||
headers,
|
||||
additionalData: { data: receipt, signature },
|
||||
nextPaymentProcessing,
|
||||
nextBillingDate: undefined,
|
||||
additionalData: { data: receipt, signature },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +52,7 @@ api.iapSubscriptionAndroid = {
|
||||
req.body.transaction.receipt,
|
||||
req.body.transaction.signature,
|
||||
req.headers,
|
||||
req.body.deferredSku,
|
||||
);
|
||||
|
||||
res.respond(200);
|
||||
|
||||
@@ -119,15 +119,7 @@ api.getSubscriptionPaymentDetails = async function getDetails (userId, subscript
|
||||
};
|
||||
};
|
||||
|
||||
api.subscribe = async function subscribe (
|
||||
sku,
|
||||
user,
|
||||
receipt,
|
||||
signature,
|
||||
headers,
|
||||
nextPaymentProcessing = undefined,
|
||||
) {
|
||||
if (!sku) throw new BadRequest(shared.i18n.t('missingSubscriptionCode'));
|
||||
function getSubCodeFromSku (sku) {
|
||||
let subCode;
|
||||
switch (sku) { // eslint-disable-line default-case
|
||||
case 'com.habitrpg.android.habitica.subscription.1month':
|
||||
@@ -143,6 +135,19 @@ api.subscribe = async function subscribe (
|
||||
subCode = 'basic_12mo';
|
||||
break;
|
||||
}
|
||||
return subCode;
|
||||
}
|
||||
|
||||
api.subscribe = async function subscribe (
|
||||
sku,
|
||||
user,
|
||||
receipt,
|
||||
signature,
|
||||
headers,
|
||||
deferredSku = undefined,
|
||||
) {
|
||||
if (!sku) throw new BadRequest(shared.i18n.t('missingSubscriptionCode'));
|
||||
const subCode = getSubCodeFromSku(sku);
|
||||
const sub = subCode ? shared.content.subscriptionBlocks[subCode] : false;
|
||||
if (!sub) throw new NotAuthorized(this.constants.RESPONSE_INVALID_ITEM);
|
||||
|
||||
@@ -156,6 +161,14 @@ api.subscribe = async function subscribe (
|
||||
const receiptObj = typeof receipt === 'string' ? JSON.parse(receipt) : receipt; // passed as a string
|
||||
const token = receiptObj.token || receiptObj.purchaseToken;
|
||||
|
||||
let existingSub;
|
||||
if (user && user.isSubscribed()) {
|
||||
existingSub = shared.content.subscriptionBlocks[user.purchased.plan.planId];
|
||||
if (existingSub === sub && user.purchased.plan.customerId === token) {
|
||||
throw new NotAuthorized(this.constants.RESPONSE_ALREADY_USED);
|
||||
}
|
||||
}
|
||||
|
||||
const existingUser = await User.findOne({
|
||||
'purchased.plan.customerId': token,
|
||||
}).exec();
|
||||
@@ -166,17 +179,34 @@ api.subscribe = async function subscribe (
|
||||
const isValidated = iap.isValidated(googleRes);
|
||||
if (!isValidated) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
|
||||
nextPaymentProcessing = nextPaymentProcessing || moment.utc().add({ days: 2 }); // eslint-disable-line no-param-reassign, max-len
|
||||
|
||||
await payments.createSubscription({
|
||||
let nextPaymentProcessing = moment.utc().add({ days: 2 }); // eslint-disable-line no-param-reassign, max-len
|
||||
let nextBillingDate;
|
||||
if (googleRes.expirationDate) {
|
||||
nextBillingDate = new Date(Number(googleRes.expirationDate));
|
||||
if (nextBillingDate < nextPaymentProcessing.toDate()) {
|
||||
nextPaymentProcessing = moment(nextBillingDate);
|
||||
}
|
||||
}
|
||||
const data = {
|
||||
user,
|
||||
customerId: token,
|
||||
paymentMethod: this.constants.PAYMENT_METHOD_GOOGLE,
|
||||
sub,
|
||||
headers,
|
||||
nextPaymentProcessing,
|
||||
nextBillingDate,
|
||||
additionalData: testObj,
|
||||
});
|
||||
};
|
||||
if (existingSub) {
|
||||
if (deferredSku) {
|
||||
const deferredSubCode = getSubCodeFromSku(deferredSku);
|
||||
data.updatedTo = shared.content.subscriptionBlocks[deferredSubCode];
|
||||
} else {
|
||||
data.updatedFrom = existingSub;
|
||||
data.updatedFrom.logic = 'payFull';
|
||||
}
|
||||
}
|
||||
await payments.createSubscription(data);
|
||||
};
|
||||
|
||||
api.noRenewSubscribe = async function noRenewSubscribe (options) {
|
||||
|
||||
@@ -214,6 +214,10 @@ async function prepareSubscriptionValues (data) {
|
||||
if (data.subscriptionId) {
|
||||
plan.subscriptionId = data.subscriptionId;
|
||||
}
|
||||
if (data.updatingTo && data.updatingTo.key) {
|
||||
// Subscription change is deferred until next payment processing
|
||||
plan.deferredPlanId = data.updatingTo.key;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -35,6 +35,7 @@ export const schema = new mongoose.Schema({
|
||||
trinkets: { $type: Number, default: 0 },
|
||||
lastHourglassReceived: Date,
|
||||
},
|
||||
deferredPlanId: String,
|
||||
}, {
|
||||
strict: true,
|
||||
minimize: false, // So empty objects are returned
|
||||
|
||||
Reference in New Issue
Block a user