Create a purchase authorization endpoint

Learn how to create an endpoint that authorizes purchases

To use Stash Pay, you need to create an endpoint that authorizes purchases. Stash calls this endpoint to notify you that the player has enough funds to cover their purchase. You then grant the player their items, and return a successful (200) response to Stash so we can charge the player.

Backends vary so it's difficult to provide specific instructions for every tech stack. This guide uses Python and Flask, but the high level steps should apply to other languages.

Prerequisites

Before working through this guide, install Python 3 and Flask. Some familiarity with Python and Flask is helpful but not required.

1. Create the endpoint

To get started, create a Python file and paste the boilerplate code below into it. It adds a route and defines a handle_transaction function. In this example, a hardcoded API key is used for validation. Don't do this in production. You should securely store API keys and secure this endpoint for production use.


from flask import Flask, request, jsonify

app = Flask(__name__)

# Securely store API keys outside of this file.
# For example purposes only, a sample API key is
# used below.

API_KEY = "cad1"

@app.route('/purchase/<player_id>', methods=['POST'])
def handle_transaction(player_id):

if __name__ == '__main__':
    app.run(debug=True)

2. Validate the API key

Before processing a request, validate the API key exists and it matches the key on record. If there's no API key passed in the request, or the API key doesn't match the one on file, a 401 error is returned.


from flask import Flask, request, jsonify

app = Flask(__name__)

# Securely store API keys outside of this file.
# For example purposes only, a sample API key is
# used below.

API_KEY = "cad1"

@app.route('/purchase/<player_id>', methods=['POST'])
def handle_transaction(player_id):
    # Validate the API key before processing the call
    api_key = request.headers.get('x-api-key')
    if not api_key or api_key != API_KEY:
        return jsonify({"error": "Unauthorized"}), 401

if __name__ == '__main__':
    app.run(debug=True)

3. Parse purchase data JSON

Purchase data includes the transaction ID and the products (passed in the items array) the player wants to buy. This data comes in JSON format, and you use it to grant players their products.


from flask import Flask, request, jsonify

app = Flask(__name__)

# Securely store API keys outside of this file.
# For example purposes only, a sample API key is
# used below.

API_KEY = "cad1"

@app.route('/purchase/<player_id>', methods=['POST'])
def handle_transaction(player_id):
    # Validate the API key before processing the call
    api_key = request.headers.get('x-api-key')
    if not api_key or api_key != API_KEY:
        return jsonify({"error": "Unauthorized"}), 401

    if request.is_json:
        try:
            # Parse the JSON content from the request
            data = request.get_json()
            # Access transactionId and items from the JSON object
            transaction_id = data['transactionId']
            items = data['items']

if __name__ == '__main__':
    app.run(debug=True)

4. Handle the purchase

After processing the purchase data, you need to write whatever custom logic is needed for handling the purchase. This generally includes validating that the player is eligible to make the purchase, and then either granting or denying the transaction.

If you want to approve the transaction, you need to return a 200 OK response to Stash so we can charge the player. All other responses result in a failed transaction.


from flask import Flask, request, jsonify

app = Flask(__name__)

# Securely store API keys outside of this file.
# For example purposes only, a sample API key is
# used below.

API_KEY = "cad1"

@app.route('/purchase/<player_id>', methods=['POST'])
def handle_transaction(player_id):
    # Validate the API key before processing the call
    api_key = request.headers.get('x-api-key')
    if not api_key or api_key != API_KEY:
        return jsonify({"error": "Unauthorized"}), 401

    if request.is_json:
        try:
            # Parse the JSON content from the request
            data = request.get_json()
            # Access transactionId and items from the JSON object
            transaction_id = data['transactionId']
            items = data['items']
            # This is where you'd trigger logic for granting
            # the player their items.
            # This example prints the player ID, transaction ID,
            # and the items purchased.
            print(f'Player ID: {player_id}')
            print(f'Transaction ID: {transaction_id}')
            for item in items:
                print(f'Item ID: {item["id"]}, Quantity: {item["quantity"]}')
            # Respond with a 200 OK status after you grant the player their
            # items. This notifies Stash that we can charge the player.
            return jsonify({"message": "Transaction processed successfully"}), 200
        except KeyError as e:
            # If required keys are missing, respond with a 400 Bad Request
            return jsonify({"error": f"Missing key: {str(e)}"}), 400
    else:
        # If the request content-type is not JSON, respond with a 400 Bad Request
        return jsonify({"error": "Request must be JSON"}), 400

if __name__ == '__main__':
    app.run(debug=True)

4. Test the endpoint

Run a local server with flask --app YOUR_PYTHON_FILE run --debug and then use Curl to test the endpoint.

curl -X POST http://127.0.0.1:5000/purchase/player_id_123 \
     -H "Content-Type: application/json" \
     -H "x-api-key: cad1" \
     -d '{
          "transactionId": "abc123",
          "items": [
            { "id": "sword_123", "quantity": 1 },
            { "id": "shield_1234", "quantity": 1 }
          ]
        }'

Next steps

If you haven't yet, work through the quickstart to learn how to use the Checkout Links API. You might also want to check out the overview or the API Reference.