<?php
// Fill these in with the information from your CoinPayments.net account.
$cp_merchant_id = '';
$cp_ipn_secret = '';
$cp_debug_email = '';
//These would normally be loaded from your database, the most common way is to pass the Order ID through the 'custom' POST field.
$order_currency = 'USD';
$order_total = 10.00;
function errorAndDie($error_msg) {
global $cp_debug_email;
if (!empty($cp_debug_email)) {
$report = 'Error: '.$error_msg."\n\n";
$report .= "POST Data\n\n";
foreach ($_POST as $k => $v) {
$report .= "|$k| = |$v|\n";
}
mail($cp_debug_email, 'CoinPayments IPN Error', $report);
}
die('IPN Error: '.$error_msg);
}
if (!isset($_POST['ipn_mode']) || $_POST['ipn_mode'] != 'hmac') {
errorAndDie('IPN Mode is not HMAC');
}
if (!isset($_SERVER['HTTP_HMAC']) || empty($_SERVER['HTTP_HMAC'])) {
errorAndDie('No HMAC signature sent.');
}
$request = file_get_contents('php://input');
if ($request === FALSE || empty($request)) {
errorAndDie('Error reading POST data');
}
if (!isset($_POST['merchant']) || $_POST['merchant'] != trim($cp_merchant_id)) {
errorAndDie('No or incorrect Merchant ID passed');
}
$hmac = hash_hmac("sha512", $request, trim($cp_ipn_secret));
if (!hash_equals($hmac, $_SERVER['HTTP_HMAC'])) {
//if ($hmac != $_SERVER['HTTP_HMAC']) { <-- Use this if you are running a version of PHP below 5.6.0 without the hash_equals function
errorAndDie('HMAC signature does not match');
}
// HMAC Signature verified at this point, load some variables.
$ipn_type = $_POST['ipn_type'];
$txn_id = $_POST['txn_id'];
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$amount1 = floatval($_POST['amount1']);
$amount2 = floatval($_POST['amount2']);
$currency1 = $_POST['currency1'];
$currency2 = $_POST['currency2'];
$status = intval($_POST['status']);
$status_text = $_POST['status_text'];
if ($ipn_type != 'button') { // Advanced Button payment
die("IPN OK: Not a button payment");
}
//depending on the API of your system, you may want to check and see if the transaction ID $txn_id has already been handled before at this point
// Check the original currency to make sure the buyer didn't change it.
if ($currency1 != $order_currency) {
errorAndDie('Original currency mismatch!');
}
// Check amount against order total
if ($amount1 < $order_total) {
errorAndDie('Amount is less than order total!');
}
if ($status >= 100 || $status == 2) {
// payment is complete or queued for nightly payout, success
} else if ($status < 0) {
//payment error, this is usually final but payments will sometimes be reopened if there was no exchange rate conversion or with seller consent
} else {
//payment is pending, you can optionally add a note to the order page
}
die('IPN OK');