Я новичок в интеграции покупок в приложениях. Это мой первый раз, но я столкнулся с проблемой.
Каждый раз, когда я совершаю транзакцию с любого устройства с любой зарегистрированной учетной записью, она автоматически сохраняется в первый раз. каждый раз входил в учетную запись (идентификатор пользователя 6718d1d4c4d8cc8ae50de132).
Я сменил учетную запись, вышел из системы и вошел в другую учетную запись в своем приложении, чтобы получить другой идентификатор пользователя, когда я попробовал совершить покупку, то же самое проблема, она сохраняется только для первого идентификатора пользователя. Я тоже пробовал разные устройства, возможно, оно было кэшировано, то же самое.
Пожалуйста, помогите, я использую сервер уведомлений Apple Store, и я получил информацию ниже, которую я декодирую.
// Shared secret and Google API variables as defined in your code
const APPLE_SHARED_SECRET = process.env.APPLE_SHARED_SECRET;
const GOOGLE_PACKAGE_NAME = 'com.example.podcella';
const GOOGLE_PRODUCT_ID_WEEKLY = 'com.podcella.weeklysubscription';
const GOOGLE_PRODUCT_ID_MONTHLY = 'com.podcella.monthlysubscription';
const GOOGLE_PRODUCT_ID_YEARLY = 'com.podcella.yearlysubscription';
// const GOOGLE_API_ACCESS_TOKEN = 'your_google_api_access_token';
// Update Subscription After Purchase
const updateSubscriptionAfterPurchase = async (req, res) => {
const { signedPayload, purchaseToken } = req.body;
// console.log('Received notification:', req.body);
try {
let paymentPlan, amount, planExpiryDate, transactionData, transactionData2;
if (signedPayload) {
const decodedPayload = jwt.decode(signedPayload, { complete: true });
transactionData = decodedPayload?.payload;
console.log('transactiondata: ', transactionData);
//second decoding
const decodedPayload2 = jwt.decode(transactionData.data.signedTransactionInfo, { complete: true });
transactionData2 = decodedPayload2?.payload;
console.log('transactiondata2: ', transactionData2);
if (!transactionData2) {
return res.status(400).json({ message: 'Apple signedPayload decoding failed' });
}
paymentPlan = mapApplePlan(transactionData2);
// amount = getAppleAmount(transactionData2);
if (transactionData2.currency === 'NGN') {
amount = transactionData2.price / 1000;
} else {
amount = transactionData2.price;
}
planExpiryDate = new Date(parseInt(transactionData2.expiresDate));
// console.log(paymentPlan);
// console.log(amount);
// console.log(planExpiryDate);
} else if (purchaseToken) {
const googleResponse = await verifyGooglePurchase(purchaseToken);
if (!googleResponse || !googleResponse.data) {
return res.status(400).json({ message: 'Google transaction verification failed' });
}
const subscriptionData = googleResponse.data;
paymentPlan = mapGooglePlan(subscriptionData);
amount = getGoogleAmount(subscriptionData);
planExpiryDate = new Date(parseInt(subscriptionData.expiryTimeMillis));
transactionData = subscriptionData; // Using for uniform structure
}
if (!paymentPlan || !amount) {
return res.status(400).json({ message: 'Invalid payment plan or amount' });
}
const user = await User.findOne({
$or: [
{ 'subscription.appleTransactionId': transactionData2?.originalTransactionId },
{ 'subscription.googlePurchaseToken': purchaseToken }
]
});
console.log(user?.id);
console.log("User updated successfully");
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
user.subscription = {
paymentPlan,
planExpiryDate,
isPremiumUser: planExpiryDate > new Date(), // Check if expired
type: planExpiryDate > new Date() ? 'active' : 'inactive',
appleTransactionId: transactionData?.original_transaction_id || null,
googlePurchaseToken: purchaseToken || null,
};
await user.save();
const transaction = await Transaction.create({
userId: user._id,
paymentPlan,
amount,
status: 'completed'
});
res.status(200).json({
message: 'Subscription updated successfully!',
transaction,
});
console.log("Transaction updated successfully");
} catch (error) {
console.error('Error updating subscription:', error);
res.status(500).json({ message: 'Error updating subscription', error: error.message });
}
};
// Apple Plan Mapping Function
function mapApplePlan(transactionData2) {
const productId = transactionData2.productId;
switch (productId) {
case 'com.podcella.weeklysubscription':
return 'weekly';
case 'com.podcella.monthlysubscription':
return 'monthly';
case 'com.podcella.yearlysubscription':
return 'yearly';
default:
return 'inactive';
}
}
// Google verification function remains the same
async function verifyGooglePurchase(purchaseToken) {
const url = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${GOOGLE_PACKAGE_NAME}/purchases/subscriptions/${GOOGLE_PRODUCT_ID}/tokens/${purchaseToken}`;
const headers = { Authorization: `Bearer ${GOOGLE_API_ACCESS_TOKEN}` };
return await axios.get(url, { headers });
}
Я хочу, чтобы транзакция обновлялась для пользователя, совершившего эту транзакцию, на данный момент получен только этот идентификатор пользователя 6718d1d4c4d8cc8ae50de132. несмотря на тестирование покупки в приложении на другом устройстве и другой учетной записи.
каждый раз всегда это 6718d1d4c4d8cc8ae50de132
Я новичок в интеграции покупок в приложениях. Это мой первый раз, но я столкнулся с проблемой. Каждый раз, когда я совершаю транзакцию с любого устройства с любой зарегистрированной учетной записью, она автоматически сохраняется в первый раз. каждый раз входил в учетную запись (идентификатор пользователя 6718d1d4c4d8cc8ae50de132). Я сменил учетную запись, вышел из системы и вошел в другую учетную запись в своем приложении, чтобы получить другой идентификатор пользователя, когда я попробовал совершить покупку, то же самое проблема, она сохраняется только для первого идентификатора пользователя. Я тоже пробовал разные устройства, возможно, оно было кэшировано, то же самое. Пожалуйста, помогите, я использую сервер уведомлений Apple Store, и я получил информацию ниже, которую я декодирую.[code]transactiondata: { notificationType: 'EXPIRED', subtype: 'VOLUNTARY', notificationUUID: '33993256-fb6b-44c2-a6a1-e183e6936711', data: { appAppleId: 6737527243, bundleId: '-X4JU4ZNDG.com.example.podcella', bundleVersion: '5', environment: 'Sandbox', signedTransactionInfo: 'eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWd....', signedRenewalInfo: 'eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJ...', status: 2 }, version: '2.0', signedDate: 1730559317958 } transactiondata2: { transactionId: '2000000762928300', originalTransactionId: '2000000759306490', webOrderLineItemId: '2000000079532551', bundleId: '-X4JU4ZNDG.com.example.podcella', productId: 'com.podcella.monthlysubscription', subscriptionGroupIdentifier: '21571853', purchaseDate: 1730558583000, originalPurchaseDate: 1730257647000, expiresDate: 1730558883000, quantity: 1, type: 'Auto-Renewable Subscription', inAppOwnershipType: 'PURCHASED', signedDate: 1730559317937, environment: 'Sandbox', transactionReason: 'RENEWAL', storefront: 'NGA', storefrontId: '143561', price: 1900000, currency: 'NGN' } [/code] ниже приведен код моей конечной точки [code]// Shared secret and Google API variables as defined in your code const APPLE_SHARED_SECRET = process.env.APPLE_SHARED_SECRET; const GOOGLE_PACKAGE_NAME = 'com.example.podcella'; const GOOGLE_PRODUCT_ID_WEEKLY = 'com.podcella.weeklysubscription'; const GOOGLE_PRODUCT_ID_MONTHLY = 'com.podcella.monthlysubscription'; const GOOGLE_PRODUCT_ID_YEARLY = 'com.podcella.yearlysubscription'; // const GOOGLE_API_ACCESS_TOKEN = 'your_google_api_access_token';
// Apple Plan Mapping Function function mapApplePlan(transactionData2) { const productId = transactionData2.productId; switch (productId) { case 'com.podcella.weeklysubscription': return 'weekly'; case 'com.podcella.monthlysubscription': return 'monthly'; case 'com.podcella.yearlysubscription': return 'yearly'; default: return 'inactive'; } }
// Google verification function remains the same async function verifyGooglePurchase(purchaseToken) { const url = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${GOOGLE_PACKAGE_NAME}/purchases/subscriptions/${GOOGLE_PRODUCT_ID}/tokens/${purchaseToken}`; const headers = { Authorization: `Bearer ${GOOGLE_API_ACCESS_TOKEN}` };
return await axios.get(url, { headers }); } [/code] Я хочу, чтобы транзакция обновлялась для пользователя, совершившего эту транзакцию, на данный момент получен только этот идентификатор пользователя 6718d1d4c4d8cc8ae50de132. несмотря на тестирование покупки в приложении на другом устройстве и другой учетной записи. каждый раз всегда это 6718d1d4c4d8cc8ae50de132