Node.js Python Go Java PHP C# Ruby
const http = require ('http' );
const { verify, envelope, OK } = require ('./merchant-sign' );
http.createServer ((req, res) => {
const chunks = [];
req.on ('data' , (c) => chunks.push (c));
req.on ('end' , () => {
const raw = Buffer.concat (chunks); // verify the raw bytes BEFORE JSON.parse
res.setHeader ('Content-Type' , 'application/json' );
if (req.method !== 'POST' || req.url !== '/wallet/balance' ) { res.statusCode = 404 ; return res.end (); }
const check = verify (SECRET_KEY, MERCHANT_CODE, req.headers, req.method, req.url, raw);
if (check !== OK) return res.end (envelope (check));
const input = JSON.parse (raw);
// Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
// Answer the exact current balance, padded to the currency precision.
res.end (envelope ('OK' , 'OK' , {"balance" :"1250.50" })); // business results are always HTTP 200
});
}).listen (8080 );from flask import Flask, request, Response
from merchant_sign import verify, envelope, OK
app = Flask (__name__)
@app.post ("/wallet/balance" )
def balance ():
raw = request.get_data () # verify the raw bytes BEFORE parsing JSON
check = verify (SECRET_KEY, MERCHANT_CODE, request.headers, "POST" , request.path, raw)
if check != OK:
return Response (envelope (check), mimetype="application/json" )
data = request.get_json ()
# Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
# Answer the exact current balance, padded to the currency precision.
return Response (envelope ("OK" , "OK" , {"balance" :"1250.50" }), mimetype="application/json" )http.HandleFunc ("POST /wallet/balance" , func (w http.ResponseWriter, r *http.Request) {
raw, _ := io.ReadAll (http.MaxBytesReader (w, r.Body, 1 <<20 )) // verify the raw bytes BEFORE decoding
w.Header ().Set ("Content-Type" , "application/json" )
if check := merchantsign.Verify (secretKey, merchantCode, r.Header, r.Method, r.URL.EscapedPath (), raw, time.Now ()); check != merchantsign.OK {
w.Write (merchantsign.Envelope (check, "" , nil ))
return
}
var in map [string ]any
_ = json.Unmarshal (raw, &in )
// Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
// Answer the exact current balance, padded to the currency precision.
w.Write (merchantsign.Envelope ("OK" , "OK" , json.RawMessage (`{"balance":"1250.50"}` ))) // always HTTP 200
})@RestController
class WalletController {
@PostMapping (value = "/wallet/balance" , produces = "application/json" )
String balance (@RequestBody byte [] raw, @RequestHeader Map<String, String> headers) throws IOException {
String check = MerchantSign.verify (SECRET_KEY, MERCHANT_CODE, headers, "POST" , "/wallet/balance" , raw, System.currentTimeMillis ());
if (!check.equals (MerchantSign.OK)) {
return "{\"code\":\"" + check + "\",\"message\":\"" + check + "\"}" ;
}
JsonNode in = new ObjectMapper ().readTree (raw); // parse only after the signature checks out
// Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
// Answer the exact current balance, padded to the currency precision.
return "{\"code\":\"OK\",\"message\":\"OK\",\"data\":" + "{\"balance\":\"1250.50\"}" + "}" ;
}
}<?php
require 'MerchantSign.php' ;
// /wallet/balance
header ('Content-Type: application/json' );
$raw = file_get_contents ('php://input' ); // verify the raw bytes BEFORE json_decode
$check = MerchantSign::verify (SECRET_KEY, MERCHANT_CODE, getallheaders (), $_SERVER['REQUEST_METHOD' ],
parse_url ($_SERVER['REQUEST_URI' ], PHP_URL_PATH), $raw);
if ($check !== MerchantSign::OK) {
echo MerchantSign::envelope ($check);
exit;
}
$in = json_decode ($raw, true );
// Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
// Answer the exact current balance, padded to the currency precision.
echo MerchantSign::envelope ('OK' , 'OK' , json_decode ('{"balance":"1250.50"}' , true ));app.MapPost ("/wallet/balance" , async (HttpRequest req) =>
{
using var ms = new MemoryStream ();
await req.Body.CopyToAsync (ms);
var raw = ms.ToArray (); // verify the raw bytes BEFORE deserializing
var headers = req.Headers.ToDictionary (h => h.Key, h => h.Value.ToString ());
var check = MerchantSign.Verify (SecretKey, MerchantCode, headers, req.Method, req.Path, raw);
if (check != MerchantSign.Ok)
return Results.Json (new { code = check, message = check });
var input = JsonDocument.Parse (raw).RootElement;
// Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
// Answer the exact current balance, padded to the currency precision.
return Results.Text ("{\"code\":\"OK\",\"message\":\"OK\",\"data\":" + "{\"balance\":\"1250.50\"}" + "}" , "application/json" );
});require 'sinatra'
require 'json'
require_relative 'merchant_sign'
post '/wallet/balance' do
content_type :json
raw = request.body.read # verify the raw bytes BEFORE JSON.parse
check = MerchantSign.verify (SECRET_KEY, MERCHANT_CODE, request.env, 'POST' , request.path_info, raw)
return MerchantSign.envelope (check) unless check == MerchantSign::OK
input = JSON.parse (raw)
# Unknown extPlayerId: PLAYER_NOT_FOUND. Currency differs from the player's: CURRENCY_MISMATCH.
# Answer the exact current balance, padded to the currency precision.
MerchantSign.envelope ('OK' , 'OK' , JSON.parse ('{"balance":"1250.50"}' ))
end