<?PHP
// Valores constantes a modificar segun el comercio

$url_tpvv='https://sis.sermepa.es/sis/realizarPago';  // URL de Sermepa para entorno real. Para URL de entorno
                                                      // de pruebas consultar el manual de comercios.
$clave='la_clave_de_tu_comercio';                     // Clave de comercio proporcionada por Sermepa.
$name='nombre_de_tu_comercio';                        // Nombre del comercio que sale en la transaccion.
$code='codigo_de_tu_comercio';                        // Codigo de comercio proporcionado por Sermepa.
$terminal='001';                                      // Terminal usado.
$currency='978';                                      // 978=Euros.
$tipoOperacion='0';                                   // Tipo de operacion. 0=Autorizacion.
$urlMerchant=''; 	// Para poder definir una URL del comercio es necesario usar PHP5
			// No es posible usar PHP4 para poder enviar en la firma la url del comercio.

?>

<?PHP
// Calculo del hash para firmar los datos.
$order = '00'.$db->f("order_id");
$amount=$db->f("order_total")*100;
$sha = new SHA;
$message = $amount.$order.$code.$currency.$clave;
$digest1 = $sha->hash_string($message);
$signature = strtoupper ($sha->hash_to_string( $digest1 ));
?>

<form action="<?php echo $url_tpvv?>" method="post">
<input type="hidden" name="cmd" value="cart" />
<input type="image" src="http://www.hardnology.com/images/servired.jpg" name="submit" alt="Pagar en modo seguro" />
<input type="hidden" name="Ds_Merchant_Amount" value="<?php echo $amount?>" />
<input type="hidden" name="Ds_Merchant_Currency" value="<?php echo $currency?>" />
<input type="hidden" name="Ds_Merchant_Order" value="<?php echo $order?>" />
<input type="hidden" name="Ds_Merchant_ProductDescription" value="Compra productos en hardnology.com" />
<input type="hidden" name="Ds_Merchant_Titular" value="<?php echo $user->first_name ?> <?php echo $user->last_name ?>" />
<input type="hidden" name="Ds_Merchant_MerchantCode" value="<?php echo $code?>" />
<input type="hidden" name="Ds_Merchant_MerchantURL" value="<?php echo $urlMerchant?>" />
<input type="hidden" name="Ds_Merchant_UrlOK" value="http://www.hardnology.com/autorizada.htm" />
<input type="hidden" name="Ds_Merchant_UrlKO" value="http://www.hardnology.com/no_autorizada.htm" />
<input type="hidden" name="Ds_Merchant_MerchantName" value="<?php echo $name?>" />
<input type="hidden" name="Ds_Merchant_ConsumerLanguage" value="001" />
<input type="hidden" name="Ds_Merchant_MerchantSignature" value="<?php echo $signature ?>" />
<input type="hidden" name="Ds_Merchant_Terminal" value="<?php echo $terminal?>" />
<input type="hidden" name="Ds_Merchant_TransactionType" value="<?php echo $tipoOperacion?>" />
</form>

<?PHP
// Algoritmo SHA-1. No hace falta entenderlo, es matematica pura y dura.

class SHA { 
	var $A, $B, $C, $D, $E;
	var $ta, $tb, $tc, $td, $te;
	var $K0_19, $K20_39, $K40_59, $K60_79; 

	var $buffer; 
	var $buffsize; 
	var $totalsize; 



	function SHA () { 
		$this->init(); 
	} 

	function init () {
		$this->A = 0x6745 << 16 | 0x2301; 
		$this->B = 0xefcd << 16 | 0xab89; 
		$this->C = 0x98ba << 16 | 0xdcfe; 
		$this->D = 0x1032 << 16 | 0x5476; 
		$this->E = 0xc3d2 << 16 | 0xe1f0; 
		$this->ta = $this->A; 
		$this->tb = $this->B; 
		$this->tc = $this->C; 
		$this->td = $this->D; 
		$this->te = $this->E; 
		$this->K0_19 = 0x5a82 << 16 | 0x7999; 
		$this->K20_39 = 0x6ed9 << 16 | 0xeba1; 
		$this->K40_59 = 0x8f1b << 16 | 0xbcdc; 
		$this->K60_79 = 0xca62 << 16 | 0xc1d6; 

		$this->buffer = array(); 
		$this->buffsize = 0; 
		$this->totalsize = 0; 
	} 

	function bytes_to_words( $block ) { 
		$nblk = array(); 
		for( $i=0; $i<16; ++$i) { 
			$index = $i * 4; 
			$nblk[$i] = 0; 
			$nblk[$i] |= ($block[$index] & 0xff) << 24; 
			$nblk[$i] |= ($block[$index+1] & 0xff) << 16; 
			$nblk[$i] |= ($block[$index+2] & 0xff) << 8; 
			$nblk[$i] |= ($block[$index+3] & 0xff); 
		} 
		return $nblk; 
	} 

	function pad_block( $block, $size ) {
		$blksize = sizeof( $block ); 
		$bits = $size * 8; 

		$newblock = $block; 
		$newblock[] = 0x80;
		while((sizeof($newblock) % 64) != 56) { 
			$newblock[] = 0; 
		}
		for ($i=0; $i<8; ++$i) { 
			$newblock[] = ($i<4) ? 0 : ($bits >> ((7-$i)*8)) & 0xff; 
		} 

		return $newblock; 
	} 

	function circ_shl( $num, $amt ) { 
		$leftmask = 0xffff | (0xffff << 16); 
		$leftmask <<= 32 - $amt; 
		$rightmask = 0xffff | (0xffff << 16); 
		$rightmask <<= $amt; 
		$rightmask = ~$rightmask; 

		$remains = $num & $leftmask; 
		$remains >>= 32 - $amt; 
		$remains &= $rightmask; 

		$res = ($num << $amt) | $remains; 

		return $res; 
	} 

	function f0_19( $x, $y, $z ) { 
		return ($x & $y) | (~$x & $z); 
	} 

	function f20_39( $x, $y, $z ) { 
		return ($x ^ $y ^ $z); 
	} 

	function f40_59( $x, $y, $z ) { 
		return ($x & $y) | ($x & $z) | ($y & $z); 
	} 

	function f60_79( $x, $y, $z ) { 
		return $this->f20_39( $x, $y, $z ); 
	} 

	function expand_block( $block ) { 
		$nblk = $block; 
		for( $i=16; $i<80; ++$i ) { 
			$nblk[$i] = $this->circ_shl( 
					$nblk[$i-3] ^ $nblk[$i-8] ^ $nblk[$i-14] ^ $nblk[$i-16], 1 
				); 
		} 

		return $nblk; 
	} 

	function print_bytes( $bytes ) { 
		$len = sizeof( $bytes ); 
		for( $i=0; $i<$len; ++$i) { 
			$str[] = sprintf(  "%02x", $bytes[$i] ); 
		} 

		print( join(  ", ", $str ) .  "\n" ); 
	} 

	function wordstr( $word ) { 
		return sprintf(  
			 "%04x%04x", ($word >> 16) & 0xffff, $word & 0xffff 
			); 
	} 

	function print_words( $words ) { 
		$len = sizeof( $words ); 
		for( $i=0; $i<$len; ++$i) { 
			$str[] = $this->wordstr( $words[$i] ); 
		} 
		 
		print( join(  ", ", $str ) .  "\n" ); 
	} 

	function hash_to_string( $hash ) { 
		$len = sizeof( $hash );
		for ($i=0; $i<$len; ++$i) { 
			$astr .= $this->wordstr( $hash[$i] ); 
		} 
		return $astr; 
	} 

	function add( $a, $b ) { 
		$ma = ($a >> 16) & 0xffff; 
		$la = ($a) & 0xffff; 
		$mb = ($b >> 16) & 0xffff; 
		$lb = ($b) & 0xffff; 

		$ls = $la + $lb; 
		 // Carry 
		if ($ls > 0xffff) { 
			$ma += 1; 
			$ls &= 0xffff; 
		} 

		$ms = $ma + $mb; 
		$ms &= 0xffff; 

		$result = ($ms << 16) | $ls; 
		return $result; 
	} 

	function process_block( $blk ) { 
		$blk = $this->expand_block( $blk ); 

		for( $i=0; $i<80; ++$i ) { 
			$temp = $this->circ_shl( $this->ta, 5 ); 
			if ($i<20) { 
				$f = $this->f0_19( $this->tb, $this->tc, $this->td ); 
				$k = $this->K0_19; 
			} 
			elseif ($i<40) { 
				$f = $this->f20_39( $this->tb, $this->tc, $this->td ); 
				$k = $this->K20_39; 
			} 
			elseif ($i<60) { 
				$f = $this->f40_59( $this->tb, $this->tc, $this->td ); 
				$k = $this->K40_59; 
			} 
			else { 
				$f = $this->f60_79( $this->tb, $this->tc, $this->td ); 
				$k = $this->K60_79; 
			} 

			$temp = $this->add( $temp, $f ); 
			$temp = $this->add( $temp, $this->te ); 
			$temp = $this->add( $temp, $blk[$i] ); 
			$temp = $this->add( $temp, $k ); 

			$this->te = $this->td; 
			$this->td = $this->tc; 
			$this->tc = $this->circ_shl( $this->tb, 30 ); 
			$this->tb = $this->ta; 
			$this->ta = $temp; 
		} 

		$this->A = $this->add( $this->A, $this->ta ); 
		$this->B = $this->add( $this->B, $this->tb ); 
		$this->C = $this->add( $this->C, $this->tc ); 
		$this->D = $this->add( $this->D, $this->td ); 
		$this->E = $this->add( $this->E, $this->te ); 
	} 

	function update ( $bytes ) { 
		$length = sizeof( $bytes ); 
		$index = 0; 

		while (($length - $index) + $this->buffsize >= 64) { 
			for( $i=$this->buffsize; $i<64; ++$i) { 
				$this->buffer[$i] = $bytes[$index + $i - $this->buffsize]; 
			} 
			$this->process_block( $this->bytes_to_words( $this->buffer ) ); 
			$index += 64; 
			$this->buffsize = 0; 
		} 

		$remaining = $length - $index; 
		for( $i=0; $i<$remaining; ++$i) { 
			$this->buffer[$this->buffisze + $i] = $bytes[$index + $i]; 
		} 
		$this->buffsize += $remaining; 
		$this->totalsize += $length; 
	} 

	function acabar() { 
		for( $i=0; $i<$this->buffsize; ++$i) { 
			$last_block[$i] = $this->buffer[$i]; 
		} 
		$this->buffsize = 0; 
		$last_block = $this->pad_block( $last_block, $this->totalsize ); 
		$index = 0; 
		$length = sizeof( $last_block ); 
		while( $index < $length ) 
		{
			$block = array(); 
			for( $i=0; $i<64; ++$i) { 
				$block[$i] = $last_block[$i + $index]; 
			} 
			$this->process_block( $this->bytes_to_words( $block ) ); 
			$index += 64; 
		} 

		$result[0] = $this->A; 
		$result[1] = $this->B; 
		$result[2] = $this->C; 
		$result[3] = $this->D; 
		$result[4] = $this->E; 

		return $result; 
	} 

	function hash_bytes( $bytes ) { 
		$this->init(); 
		$this->update( $bytes ); 
		return $this->acabar(); 
	} 

	function hash_string( $str ) { 
		$len = strlen( $str ); 
		for($i=0; $i<$len; ++$i) { 
			$bytes[] = ord( $str[$i] ) & 0xff; 
		} 
		return $this->hash_bytes( $bytes ); 
	} 
}
?>