├── .gitignore ├── README.md ├── package.json ├── s-project.json ├── s-resources-cf.json └── validate ├── event.json ├── handler.js ├── lib └── index.js └── s-function.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | dist 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directory 28 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 29 | node_modules 30 | 31 | #IDE 32 | **/.idea 33 | 34 | #OS 35 | .DS_Store 36 | .tmp 37 | 38 | #SERVERLESS 39 | admin.env 40 | .env 41 | 42 | #Ignore _meta folder 43 | _meta -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serverless In App Purchase Validator 2 | 3 | [![serverless](http://public.serverless.com/badges/v3.svg)](http://www.serverless.com) 4 | 5 | This project create a lambda function with endpoint for validate in app purchase receipts using https://github.com/voltrue2/in-app-purchase 6 | 7 | ## Install 8 | 9 | Make sure you have the [Serverless Framework](http://www.serverless.com) installed and you're using Node.js v4.0+. 10 | ``` 11 | npm install serverless -g 12 | ``` 13 | 14 | Install the project using Serverless: 15 | ``` 16 | serverless project install serverless-in-app-purchase-validator 17 | ``` 18 | 19 | Install project dependencies via npm: 20 | ``` 21 | npm install 22 | ``` 23 | 24 | Deploy your functions and endpoints: 25 | ``` 26 | serverless dash deploy 27 | ``` 28 | 29 | ##Alternative Install 30 | 31 | If issues arise during installation, the steps below can be taken to install the project and initialize it. 32 | 33 | Open a command line terminal and `cd` to the location where you will be placing the serverless-in-app-purchase-validator project. 34 | 35 | Clone the project directly from Github: 36 | 37 | ``` 38 | git clone git@github.com:movielala/serverless-in-app-purchase-validator.git 39 | ``` 40 | 41 | Enter the serverless-in-app-purchase-validator folder that was just created: 42 | ``` 43 | cd serverless-in-app-purchase-validator 44 | ``` 45 | 46 | Install all npm dependencies: 47 | ``` 48 | npm install 49 | ``` 50 | 51 | Initialize the project: 52 | ``` 53 | serverless project init 54 | ``` 55 | 56 | Deploy your functions and endpoints: 57 | ```yout 58 | serverless dash deploy 59 | ``` 60 | 61 | ## Examples 62 | ### Apple 63 | curl -H "Content-Type: application/json" -X POST -d '{"receipt":"ewoJInNpZ25hdHVyZSIgPSAiQXBNVUJDODZBbHpOaWtWNVl0clpBTWlKUWJLOEVk\nZVhrNjNrV0JBWHpsQzhkWEd1anE0N1puSVlLb0ZFMW9OL0ZTOGNYbEZmcDlZWHQ5\naU1CZEwyNTBsUlJtaU5HYnloaXRyeVlWQVFvcmkzMlc5YVIwVDhML2FZVkJkZlcr\nT3kvUXlQWkVtb05LeGhudDJXTlNVRG9VaFo4Wis0cFA3MHBlNWtVUWxiZElWaEFB\nQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NHVVVrVTNaV0FTMU1BMEdDU3FHU0liM0RR\nRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pT\nQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlF\nRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIz\nSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEE1TURZeE5U\nSXlNRFUxTmxvWERURTBNRFl4TkRJeU1EVTFObG93WkRFak1DRUdBMVVFQXd3YVVI\nVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVr\nRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NX\nNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZ\nMEFNSUdKQW9HQkFNclJqRjJjdDRJclNkaVRDaGFJMGc4cHd2L2NtSHM4cC9Sd1Yv\ncnQvOTFYS1ZoTmw0WElCaW1LalFRTmZnSHNEczZ5anUrK0RyS0pFN3VLc3BoTWRk\nS1lmRkU1ckdYc0FkQkVqQndSSXhleFRldngzSExFRkdBdDFtb0t4NTA5ZGh4dGlJ\nZERnSnYyWWFWczQ5QjB1SnZOZHk2U01xTk5MSHNETHpEUzlvWkhBZ01CQUFHamNq\nQndNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqQkJnd0ZvQVVOaDNvNHAyQzBn\nRVl0VEpyRHRkREM1RllRem93RGdZRFZSMFBBUUgvQkFRREFnZUFNQjBHQTFVZERn\nUVdCQlNwZzRQeUdVakZQaEpYQ0JUTXphTittVjhrOVRBUUJnb3Foa2lHOTJOa0Jn\nVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUVhU2JQanRtTjRDL0lC\nM1FFcEszMlJ4YWNDRFhkVlhBZVZSZVM1RmFaeGMrdDg4cFFQOTNCaUF4dmRXLzNl\nVFNNR1k1RmJlQVlMM2V0cVA1Z204d3JGb2pYMGlreVZSU3RRKy9BUTBLRWp0cUIw\nN2tMczlRVWU4Y3pSOFVHZmRNMUV1bVYvVWd2RGQ0TndOWXhMUU1nNFdUUWZna1FR\nVnk4R1had1ZIZ2JFL1VDNlk3MDUzcEdYQms1MU5QTTN3b3hoZDNnU1JMdlhqK2xv\nSHNTdGNURXFlOXBCRHBtRzUrc2s0dHcrR0szR01lRU41LytlMVFUOW5wL0tsMW5q\nK2FCdzdDMHhzeTBiRm5hQWQxY1NTNnhkb3J5L0NVdk02Z3RLc21uT09kcVRlc2Jw\nMGJzOHNuNldxczBDOWRnY3hSSHVPTVoydG04bnBMVW03YXJnT1N6UT09IjsKCSJw\ndXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdS\naGRHVXRjSE4wSWlBOUlDSXlNREV5TFRBMExUTXdJREE0T2pBMU9qVTFJRUZ0WlhK\ncFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkltOXlhV2RwYm1Gc0xYUnlZVzV6WVdO\nMGFXOXVMV2xrSWlBOUlDSXhNREF3TURBd01EUTJNVGM0T0RFM0lqc0tDU0ppZG5K\neklpQTlJQ0l5TURFeU1EUXlOeUk3Q2draWRISmhibk5oWTNScGIyNHRhV1FpSUQw\nZ0lqRXdNREF3TURBd05EWXhOemc0TVRjaU93b0pJbkYxWVc1MGFYUjVJaUE5SUNJ\neElqc0tDU0p2Y21sbmFXNWhiQzF3ZFhKamFHRnpaUzFrWVhSbExXMXpJaUE5SUNJ\neE16TTFOems0TXpVMU9EWTRJanNLQ1NKd2NtOWtkV04wTFdsa0lpQTlJQ0pqYjIw\ndWJXbHVaRzF2WW1Gd2NDNWtiM2R1Ykc5aFpDSTdDZ2tpYVhSbGJTMXBaQ0lnUFNB\naU5USXhNVEk1T0RFeUlqc0tDU0ppYVdRaUlEMGdJbU52YlM1dGFXNWtiVzlpWVhC\nd0xrMXBibVJOYjJJaU93b0pJbkIxY21Ob1lYTmxMV1JoZEdVdGJYTWlJRDBnSWpF\nek16VTNPVGd6TlRVNE5qZ2lPd29KSW5CMWNtTm9ZWE5sTFdSaGRHVWlJRDBnSWpJ\nd01USXRNRFF0TXpBZ01UVTZNRFU2TlRVZ1JYUmpMMGROVkNJN0Nna2ljSFZ5WTJo\naGMyVXRaR0YwWlMxd2MzUWlJRDBnSWpJd01USXRNRFF0TXpBZ01EZzZNRFU2TlRV\nZ1FXMWxjbWxqWVM5TWIzTmZRVzVuWld4bGN5STdDZ2tpYjNKcFoybHVZV3d0Y0hW\neVkyaGhjMlV0WkdGMFpTSWdQU0FpTWpBeE1pMHdOQzB6TUNBeE5Ub3dOVG8xTlNC\nRmRHTXZSMDFVSWpzS2ZRPT0iOwoJImVudmlyb25tZW50IiA9ICJTYW5kYm94IjsK\nCSJwb2QiID0gIjEwMCI7Cgkic2lnbmluZy1zdGF0dXMiID0gIjAiOwp9", "platform": "apple"}' https://your-api-gateway.your-region.amazonaws.com/your-stage/validate 64 | 65 | ### Android 66 | Not tested 67 | ### Amazon 68 | Not tested 69 | ### Windows 70 | Not tested 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-in-app-purchase-validator", 3 | "version": "0.0.2", 4 | "description": "A Serverless Project and its Serverless Plugin dependencies.", 5 | "author": "Muhammet (https://github.com/muhammet)", 6 | "license": "MIT", 7 | "private": false, 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/movielala/serverless-in-app-purchase-validator" 11 | }, 12 | "dependencies": { 13 | "in-app-purchase": "^1.1.5", 14 | "serverless-optimizer-plugin": "^2.5.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /s-project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-in-app-purchase-validator", 3 | "custom": {}, 4 | "plugins": [ 5 | "serverless-optimizer-plugin" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /s-resources-cf.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "The AWS CloudFormation template for this Serverless application's resources outside of Lambdas and Api Gateway", 4 | "Resources": { 5 | "IamRoleLambda": { 6 | "Type": "AWS::IAM::Role", 7 | "Properties": { 8 | "AssumeRolePolicyDocument": { 9 | "Version": "2012-10-17", 10 | "Statement": [ 11 | { 12 | "Effect": "Allow", 13 | "Principal": { 14 | "Service": [ 15 | "lambda.amazonaws.com" 16 | ] 17 | }, 18 | "Action": [ 19 | "sts:AssumeRole" 20 | ] 21 | } 22 | ] 23 | }, 24 | "Path": "/" 25 | } 26 | }, 27 | "IamPolicyLambda": { 28 | "Type": "AWS::IAM::Policy", 29 | "Properties": { 30 | "PolicyName": "${stage}-${project}-lambda", 31 | "PolicyDocument": { 32 | "Version": "2012-10-17", 33 | "Statement": [ 34 | { 35 | "Effect": "Allow", 36 | "Action": [ 37 | "logs:CreateLogGroup", 38 | "logs:CreateLogStream", 39 | "logs:PutLogEvents" 40 | ], 41 | "Resource": "arn:aws:logs:${region}:*:*" 42 | } 43 | ] 44 | }, 45 | "Roles": [ 46 | { 47 | "Ref": "IamRoleLambda" 48 | } 49 | ] 50 | } 51 | } 52 | }, 53 | "Outputs": { 54 | "IamRoleArnLambda": { 55 | "Description": "ARN of the lambda IAM role", 56 | "Value": { 57 | "Fn::GetAtt": [ 58 | "IamRoleLambda", 59 | "Arn" 60 | ] 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /validate/event.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /validate/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lib = require('./lib'); 4 | 5 | module.exports.handler = function(event, context, cb) { 6 | lib.validate(event, function(error, response) { 7 | return context.done(error, response); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /validate/lib/index.js: -------------------------------------------------------------------------------- 1 | var iap = require('in-app-purchase'); 2 | 3 | iap.config({ 4 | verbose: true 5 | }); 6 | 7 | module.exports.validate = function(event, cb) { 8 | console.log(event); 9 | var platform; 10 | 11 | if (event.platform == 'apple') { 12 | platform = iap.APPLE 13 | } else if (event.platform == 'android') { 14 | platform = iap.GOOGLE 15 | } else if (event.platform == 'windows') { 16 | platform = iap.WINDOWS 17 | } else if (event.platform == 'amazon') { 18 | platform = iap.AMAZON 19 | } else { 20 | cb("platform param is invalid"); 21 | } 22 | 23 | iap.validate(platform, event.receipt, function (error, response) { 24 | if (error) { 25 | cb(null, { success: false, error: error }); 26 | } else { 27 | cb(null, { success: iap.isValidated(response), error: null }); 28 | } 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /validate/s-function.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "validate", 3 | "runtime": "nodejs4.3", 4 | "description": "Serverless Lambda function for project: serverless-in-app-purchase-validator", 5 | "customName": false, 6 | "customRole": false, 7 | "handler": "handler.handler", 8 | "timeout": 6, 9 | "memorySize": 1024, 10 | "authorizer": {}, 11 | "custom": { 12 | "excludePatterns": [], 13 | "optimize": true 14 | }, 15 | "endpoints": [ 16 | { 17 | "path": "validate", 18 | "method": "POST", 19 | "type": "AWS", 20 | "authorizationType": "none", 21 | "authorizerFunction": false, 22 | "apiKeyRequired": false, 23 | "requestParameters": {}, 24 | "responses": { 25 | "400": { 26 | "statusCode": "400" 27 | }, 28 | "default": { 29 | "statusCode": "200", 30 | "responseParameters": {}, 31 | "responseModels": { 32 | "application/json;charset=UTF-8": "Empty" 33 | }, 34 | "responseTemplates": { 35 | "application/json;charset=UTF-8": "" 36 | } 37 | } 38 | } 39 | } 40 | ], 41 | "events": [], 42 | "environment": { 43 | "SERVERLESS_PROJECT": "${project}", 44 | "SERVERLESS_STAGE": "${stage}", 45 | "SERVERLESS_REGION": "${region}" 46 | }, 47 | "vpc": { 48 | "securityGroupIds": [], 49 | "subnetIds": [] 50 | } 51 | } 52 | --------------------------------------------------------------------------------