본문 바로가기

진리는어디에/Python

구글/iOS 인앱 결제 서버 검증 - Python (In-app purchase server side verification in Python)

iOS

import urllib, urllib2
import json
import datetime
import base64 

class IOSInappPurchaseVerifier :
	url = "https://sandbox.itunes.apple.com/verifyReceipt"
	password = "PASSWORD"

	# receipt data should be encoded by base64
	def verify(self, receipt, signature) :
		req = { "receipt-data": receipt,"password": IOSInappPurchaseVerifier.password }
		headers = {'Content-Type': 'text/Json; charset=utf-8'}
		req_json = json.dumps(req)
		request = urllib2.Request(IOSInappPurchaseVerifier.url, req_json, headers)
		response = urllib2.urlopen(request)
		receipt_json = json.loads(response.read())
        
		print receipt_json
        
		result = {}
		result["transaction_id"] = ""
		result["result"] = False
		result["purchase_date"] = 0
		result["product_id"] = ""
        
		if 0 == receipt_json["status"] :
			result["transaction_id"] = receipt_json["receipt"]["transaction_id"]
			result["product_id"] = receipt_json["receipt"]["product_id"]
			result["purchase_date"] = int(receipt_json["receipt"]["purchase_date_ms"])/1000
			result["result"] = (0 == receipt_json["status"])
		return result

Google

python3으로 넘어오면서 pycrypto 라이브러리가 더 이상 없데이트가 없고 pycrptodome을 대신 사용하라고 합니다. 특히 윈도우에서 pip install pycrypto를 할려고 치면 무슨 에러가 그렇게 많이 뜨는지...

  • pip install pycryptodome
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
import base64 
import json

public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAncSa+ODNNTrh3aHTrof0SC7sd49UrNk/wDSaG+9h/cyV/9FqlXRWyy81MQHmyjshrvHV+ju943IyK+oNpSixA+tYWkeGz0xX181e6zhI+mm+7tVslJL5ZnGwYxQ1FpiyfUlMsjYzx1NP9iJtv8tYzLefz4S3lsJDMMa/us7nD5kJrcBN+GUPosebUC6vqCiTtpt+a27EP3ndaTbYP6zu27r6WccZRqsa2IMkMGxMHiEmdklfyws6waYhP8vy/H5OBucZ9Ub+psxc11h+ChGNPCq576owCCvjS7xwnrjjo8z8PkfOKyVPu1Z239X4j1OxW6HOILUVt9lZAkC+pQ0YcQIDAQAB"
receipt = """{
        \"orderId\":\"12999763169054705758.1304033884998335\",
        \"packageName\":\"com.weredsoft.tkBattleSAGA\",
        \"item_id\":\"gold_50000\",
        \"productId\":\"tk_jewel_1000\",
        \"purchaseTime\":1413946141167,
        \"purchaseState\":0,
        \"purchaseToken\":\"hkbmcaobapebfhhjkpkfngbi.AO-J1Oyj3JU6ky2IR_Ugpw-9Cgr94vStv3Ct-ieVYLuBBTyO2l7ACemuFP8-8_32ffx9miJZZD5hrNAmkLqvS-PNCEMf2jL-pffIdfD5JOlcdSc7cPG3cjQQQcB70DHrJn2f_kyqsX3-\"
    }"""
signature = "CY9AB+ZBJDcAKzl0zXQqwXudpDXPsEwVmy7s1Uc+uItTXx5FMszKWUqKqR9sjkxnyqxIoV/sLZ2S+dKrlD1VjlY3NB5j/WfPDoXExCbpLu0/pRGGM0Wkk2IyFvODSFniXyoQJpZ1oMkwai8KxsLdDKqW+IMM+kzf1ruAGyybIyQGU/vXALv/5aYBS9XPncYF7Xq7bdAATGD4lS2lBDG6YWQqy1cErXDYco777BJ6UYZ8tZvYkMo6vMqVt2s7kbkPONPS038RyW2OxT9tBFThHyuVc7g88OaWUNoDXn5lqI0vGkKmcXKSY5L4/NfT+o8NpRKlQGf7IOe+At++B/nV8A=="

pem = ""
pem += "-----BEGIN PUBLIC KEY-----\n"
for start in range(0, len(public_key), 64) :
    pem += public_key[start:start+64]+"\n"
pem += "-----END PUBLIC KEY-----"

key = RSA.importKey(pem)
verifier = PKCS1_v1_5.new(key)

def verify(receipt, signature):
    decoded_signature = base64.b64decode(signature)
    data = SHA.new(receipt.encode("utf-8"))
    
    result = {}
    result["transaction_id"] = ""
    result["product_id"] = ""
    result["purchase_date"] = 0
    result["result"] = False

    if(1 == verifier.verify(data, decoded_signature)) :
        receipt_json = json.loads(receipt)
        result["transaction_id"] = receipt_json["orderId"]
        result["product_id"] = receipt_json["productId"]
        result["purchase_date"] = int(receipt_json["purchaseTime"])/1000
        result["result"] = True

    return result

result = verify(receipt, signature)
print(result["result"])

[진리는어디에] - PHP로 구글/iOS 인앱 결제 검증 구현(In-app purchase server side verification in PHP)

[진리는어디에] - C++로 구글 인앱 결제 검증 구현(Google Play in-app billing server side verification in C++)

 

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!