In this article, we'll dive into how to verify one-time (managed) products on your server after an in-app purchase is completed on your Android app. We'll use TypeScript on a Node.js server, but the logic can be adapted to any backend framework.
Photo by CardMapr.nl on Unsplash
1. Add the service account key
Save the service account key with Android Publisher permission in your project folder. If you don't know how to get this service account key, then read this article.
2. Store Product Information
Ensure that all product IDs set up on the Play Store, along with their associated prices, are saved in your database.
3. Setup the API
Create a POST API endpoint /play_store/managed_products/verify
4. Add Authorization
Implement authorization checks for this API to secure it. For simplicity, we will skip this step here.
5. Validate the Request
Ensure the request body contains the following parameters:
a. packageName: The application ID of your Android app.
b. productId: The ID of the product for which the payment was made.
c. purchaseToken: The token received after successful payment.
6. Install googleapis package
npm i googleapis
7. Create the Controller Class with verify method
import { google } from "googleapis"; export class PaymentsController { /** * Verify play store managed product in-app purchase */ async playStoreManagedProductVerify(req: any, res: any): Promise<void> { const {packageName, productId, purchaseToken} = req.body; const auth = new google.auth.GoogleAuth({ keyFile: "path/to/service/account/key/json", scopes: ["https://www.googleapis.com/auth/androidpublisher"], }); const androidPublisher = google.androidpublisher({ auth, version: "v3", params: { sandbox: true }, }); const res = await androidPublisher.purchases.products.get({ packageName: packageName, productId: productId, token: purchaseToken, }); if (res.data.purchaseState === 0) { console.log(res.data); // TODO: Handle the verification response res.send({message: "Payment verified successfully"}); } else { res.status(400).send({message: "Failed to verify the payment"}); } } }
8. Handling the Verification Response
You will receive a response like this after verification.
{ purchaseTimeMillis: '1715878598633', purchaseState: 0, consumptionState: 1, developerPayload: '', orderId: 'GPA.3389-9282-7070-74559', purchaseType: 0, acknowledgementState: 1, kind: 'androidpublisher#productPurchase', regionCode: 'IN' }
Upon receiving a successful response from Google Play:
a. Check for Duplicate Orders: Verify if the order ID already exists in your database.
If it does, respond with an error message: "This payment was already captured".
If not, proceed to save the transaction.
b. Update User Wallet: Retrieve the product's price using product id from your database, subtract the Play Store fee and any other applicable fees, and then increment the user's wallet balance accordingly.
c. Save Transaction Details: Store userId, purchaseTimeMillis, orderId , productId, amount, fees, etc. in your transactions table.
Conclusion
By following these steps, you can ensure secure and accurate verification of in-app purchases on your server. This process helps maintain the integrity of your financial transactions and ensures that users receive their purchased items or credits promptly.
Feel free to adapt this guide to fit your specific requirements and backend framework. Happy coding!