Help. Converting php to java

Hi all

Are there any php and java developers that could please translate this php code into Java?

My Iast 50 attempts have all been met with “bad request” errors.
Basically, I am unsure how to create the signature, and what variables do I need to json post ??

/ Your API Secret from your user vendor settings
$api_secret = ‘sec_live_zxyxwvutsrqponmlkjihgfedcba0987654321zxyxwvutsrqponmlkj’;

// The payload to be sent.
$payload = [
‘payment_id’ => ‘7ce25b4dc0’,
‘vendor_address’ => ‘etn-it-0abc123def456’

// Generate the signature
$signature = hash_hmac(‘sha256’, json_encode

/ Post the request.
$ch = curl_init(‘removed link due to blocking it’);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
‘Content-Type: application/json’,
'ETN-SIGNATURE: ’ . $signature
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);

// Decode the JSON result into an array.
$result = json_decode($result);

// Check the result.
if ($result[‘status’] === 1) {
// Payment made.
echo “Payment made for " . $result[‘amount’] . " ETN”;
} elseif ($result[‘status’] == 0) {
// Payment not made.
} else {
// Invalid request (e.g. invalid signature).

Hi Steve,

Thanks for your interest in the vendor Beta programme.

Taken from the API Guide, the Signature when polling for payment confirmation is a SHA-256 hash of the JSON payload (vendor address & paymentId) using your API Secret.

If you share your current progress, hopefully some Java developers can reply to help.


1 Like


Ok after ALOT of playing, I ‘think’ I have it working on my end.
Issue is: Finding guinea pigs to send me 10 ETN so I can test it! :rofl:

Right now, I’ve set a 10 minute time out on the screen. This is just for testing purposes and will likely be limited to about 1 minute. I’ve also hard-coded my secret, vendor id, sales ids etc into the code - which I will later move into MSSQL database and encrypt.

Im aiming for a phone-to-phone QR code scan, and as soon as the buyer hits SEND - the payment is picked up and the POS prints the receipt.

every 2 seconds, the payment check will be fired. I could take this down to approx 1.2 seconds - just to avoid getting blocked by Electroneums API server.
After the alloted time out expires, a warning message is displayed and the screen is dumped back to the sale - forcing the sale to use another option (or retry etn).
If the status message comes back as 1 (received), a message pops up saying payment has been received, and a receipt is printed / emailed for the customer.

                        int timeout = 600;
                            final TextView timeoutview = findViewById(;
                              cTimer = new CountDownTimer(600000, 2000) {
                         public void onTick(long millisUntilFinished) {
                            timeout = timeout -2;  
// trying to smooth this to 1 second intervals, but dont want to get banned from the API!!!
                            timeoutview.setText("Time out in " + timeout + "s");
                            new SendPostRequest().execute();
                            if (paymentstatus ==1){
                                Toast.makeText(pay_etn.this, "!!!" + paymentstatusmessage + "!!!", Toast.LENGTH_SHORT).show();
                        public void onFinish() {
                            if (paymentstatus ==0)
                                Toast.makeText(pay_etn.this,"Warning: Payment confirmation timed out (10 minutes)", Toast.LENGTH_SHORT).show();
 public static String hashMac(String text, String secretKey)
            throws SignatureException {
        try {
            Key sk = new SecretKeySpec(secretKey.getBytes(), HASH_ALGORITHM);
            Mac mac = Mac.getInstance(sk.getAlgorithm());
            final byte[] hmac = mac.doFinal(text.getBytes());
            return toHexString(hmac);
        } catch (NoSuchAlgorithmException e1) {
            // throw an exception or pick a different encryption method
            throw new SignatureException(
                    "error building signature, no such algorithm in device "
                            + HASH_ALGORITHM);
        } catch (InvalidKeyException e) {
            throw new SignatureException(
                    "error building signature, invalid key " + HASH_ALGORITHM);
   private static final String HASH_ALGORITHM = "HmacSHA256";
    public static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        Formatter formatter = new Formatter(sb);
        for (byte b : bytes) {
            formatter.format("%02x", b);
        return sb.toString();
    public class SendPostRequest extends AsyncTask<String, Void, String> {
        protected void onPreExecute() {
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse response;
        protected String doInBackground(String... arg0) {
            try {
                URL url = new URL(""); // here is your URL path
                JSONObject json = new JSONObject();
                json.put("payment_id", paymentidgoeshere);
                json.put("vendor_address", vendoraddressgoeshere);
                String signature = hashMac(json.toString(), secretidkeygoeshere);
                HttpPost request = new HttpPost("");
                StringEntity params = new StringEntity(json.toString());
                request.addHeader("content-type", "application/json");
                request.addHeader("Accept", "application/json");
                request.addHeader("ETN-SIGNATURE", signature);
               response = httpClient.execute(request);
                BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                StringBuilder builder = new StringBuilder();
                String str = "";
                while ((str = rd.readLine()) != null) {
                String text = builder.toString();
                Log.w("TAG", "doInBackground: " +text );
                String split[] = text.split(",");
                String statussplit[] = split[0].split(": ");
                paymentstatus = Integer.valueOf(statussplit[1]);
                Log.w("TAG", "doInBackground: STATUS =  " + paymentstatus );
                String split2[] = split[1].split(": ");
                paymentstatusmessage = split2[1].replaceAll("[-\\[\\]^/,'*:.!><~@#$%+=?|\"\\\\()]+", "");
                Log.w("TAG", "doInBackground: Message =  " + paymentstatusmessage );
            } catch (Exception e) {
                return new String("Exception: " + e.getMessage());
            } finally {
            return response.toString();



Awesome stuff! Thanks

1 Like

Awesome stuff @SteveElliott !

Tip: It helps to format the code in the reply using the preformatted text button. That’s the little button on the editor that looks like </>. In that way your code is nicely formatted and easier to read.

Thanks for sharing this!


Hi Steve!


I absolutely LOVE that video. Well done for being the first to post an integration - despite having to port it to java!

Just to answer one part of the video - about using the full ETN address as opposed to being issued a new vendor address…

If we had used a standard ETN address then you would have a potential situation where someone who had an exchange app on their phone might scan a QR code in a shop (where it says “PAY WITH ELECTRONEUM”). The exchange app would see a valid ETN wallet and allow the payment to go OUT of the exchange towards the vendor. The person would stand at the till for a couple of minutes while everyone was confused, but the till would never say it had arrived (remember you’d need to wait for exchange to action it, and blockchain to confirm it). The customer would walk away without their coffee - and then later an UNKNOWN transaction would appear in the vendors account, with no way to contact the owner of the funds.

By using a unique instant payment vendor wallet - that is (as you rightly surmised) intrinsically linked to their true ETN wallet address - the user is FORCED to use the Electroneum APP. Any attempt to pay in the store via command line wallet access, or exchange wallet would result in a message preventing them sending the funds.

I should make sure I cover this in a video at some point and include that reason in the documentation. We don’t want anyone losing their ETN!

Your video missed the other end of the transaction, which is a shame as I think viewers would love to see it! The phone app would have immediately displayed YOUR logo on the phone and both the ETN amount and an approx value in local currency, before asking if the customer wishes to continue with the transaction.

Keep up the good work, we can’t wait to see what else comes in, we are going to start looking for partners to integrate ETN in to payment gateways etc. as of now!

All the best,


Loving this progress guys! Breaking new barriers…

1 Like


Thank you SO much Richard!
I am utterly impressed with the entire Vendor API system and how easy it was to actually get it going!
(despite the headaches of trying to learn Java JSON posts from scratch)

And thank you also for explaining the reasoning behind the vendor wallet, these are things I’ve never had to think about - so I’m glad someone over at Electroneum HQ is!

I do have a nice screenshot on my phone from the guy (Cryptoman976) on the other end of the transaction where my Store Name and the $etn value appeared :grinning:
Lets see if I can post it…

Sorry for the swearing! I’d been trying for hours to get some kind of response, and I’d filmed the last 20 or so failed attempts. This one caught me by surprise! I had literally picked up my coffee for a mouthful when it suddenly completed the transaction.

If you have the time, I’d like to make some comments:

  1. Refunds:
    We will eventually need the ability to select a transaction in the wallet/app and ‘refund’ / reverse the
    payment back to the sender (minus TX costs) as this is a staple requirement of any true currency, and
    especially of any vendor.

  2. Showing the Transaction ID:
    Id love it if the Transaction ID could be shown in that screenshot above, along with the company logo,
    name and $ value. Its not important, just nice to have in multiple places for checking.

And that’s about it. Everything else is great.
Have an awesome weekend Richard, you and the team.



We are working on the refund (and partial refund) system as we speak.

We don’t have a blockchain TX ID at this point, so we can’t display it there I’m afraid. we might add an API endpoint and/or second webhook to bring that information to the database once the required blockchain confirmations have taken place.




Thanks again !

I can’t wait to test out refunds, and the fact that you are doing partial refunds is excellent. It’s something I’m currently trying to figure out too. It gets more difficult on my end when someone buys 10 of the same item, but returns one. Lots of database searches and updates.

I also saw the post you made regarding geo location meta data, and the potential for turning that into a directory/ guide. :wink:

Can I ask how the Apple cloud based miner is coming along ? I’m strictly Android, but am quite interested in what form it will take.

And thanks for the tweet out !
Again, sorry for the surprised swearing :rofl:

1 Like