Jump to content

Managing Stripe objects? wah?


Augury
Go to solution Solved by Augury,

Recommended Posts

Stripe transactions return a large object tagged urinary array.

brace yourself

object(Stripe_Object)#108 (5) {
  ["_apiKey":protected]=>
  NULL
  ["_values":protected]=>
  array(1) {
    ["id"]=>
    object(Stripe_Charge)#52 (5) {
      ["_apiKey":protected]=>
      string(32) "sk_test_wM8hH8PRkca2JUx5CUxo80FA"
      ["_values":protected]=>
      array(20) {
        ["id"]=>
        string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
        ["object"]=>
        string(6) "charge"
        ["created"]=>
        int(1394249960)
        ["livemode"]=>
        bool(false)
        ["paid"]=>
        bool(true)
        ["amount"]=>
        int(12200000)
        ["currency"]=>
        string(3) "usd"
        ["refunded"]=>
        bool(false)
        ["card"]=>
        object(Stripe_Card)#55 (5) {
          ["_apiKey":protected]=>
          string(32) "sk_test_wM8hH8PRkca2JUx5CUxo80FA"
          ["_values":protected]=>
          array(19) {
            ["id"]=>
            string(29) "card_103cr12FbnVF9TNR87RIz7Z9"
            ["object"]=>
            string(4) "card"
            ["last4"]=>
            string(4) "4242"
            ["type"]=>
            string(4) "Visa"
            ["exp_month"]=>
            int(1)
            ["exp_year"]=>
            int(2045)
            ["fingerprint"]=>
            string(16) "UWeI9V7h9H0Arx76"
            ["customer"]=>
            NULL
            ["country"]=>
            string(2) "US"
            ["name"]=>
            string(17) "Barry Leibenstien"
            ["address_line1"]=>
            string(16) "125 North Street"
            ["address_line2"]=>
            string(12) "Second floor"
            ["address_city"]=>
            string( "New York"
            ["address_state"]=>
            string(2) "NY"
            ["address_zip"]=>
            string(5) "90210"
            ["address_country"]=>
            NULL
            ["cvc_check"]=>
            NULL
            ["address_line1_check"]=>
            string(4) "pass"
            ["address_zip_check"]=>
            string(4) "pass"
          }
          ["_unsavedValues":protected]=>
          object(Stripe_Util_Set)#56 (1) {
            ["_elts":"Stripe_Util_Set":private]=>
            array(0) {
            }
          }
          ["_transientValues":protected]=>
          object(Stripe_Util_Set)#57 (1) {
            ["_elts":"Stripe_Util_Set":private]=>
            array(0) {
            }
          }
          ["_retrieveOptions":protected]=>
          array(0) {
          }
        }
        ["captured"]=>
        bool(true)
        ["refunds"]=>
        array(0) {
        }
        ["balance_transaction"]=>
        string(28) "txn_103cr12FbnVF9TNRFCXP77yw"
        ["failure_message"]=>
        NULL
        ["failure_code"]=>
        NULL
        ["amount_refunded"]=>
        int(0)
        ["customer"]=>
        NULL
        ["invoice"]=>
        NULL
        ["description"]=>
        string(13) "write it NIKE"
        ["dispute"]=>
        NULL
        ["metadata"]=>
        object(Stripe_AttachedObject)#58 (5) {
          ["_apiKey":protected]=>
          string(32) "sk_test_wM8hH8PRkca2JUx5CUxo80FA"
          ["_values":protected]=>
          array(1) {
            ["email"]=>
            string(26) "hatemail@hurtmail.com"
          }
          ["_unsavedValues":protected]=>
          object(Stripe_Util_Set)#59 (1) {
            ["_elts":"Stripe_Util_Set":private]=>
            array(0) {
            }
          }
          ["_transientValues":protected]=>
          object(Stripe_Util_Set)#60 (1) {
            ["_elts":"Stripe_Util_Set":private]=>
            array(0) {
            }
          }
          ["_retrieveOptions":protected]=>
          array(0) {
          }
        }
      }
      ["_unsavedValues":protected]=>
      object(Stripe_Util_Set)#53 (1) {
        ["_elts":"Stripe_Util_Set":private]=>
        array(0) {
        }
      }
      ["_transientValues":protected]=>
      object(Stripe_Util_Set)#54 (1) {
        ["_elts":"Stripe_Util_Set":private]=>
        array(0) {
        }
      }
      ["_retrieveOptions":protected]=>
      array(0) {
      }
    }
  }
  ["_unsavedValues":protected]=>
  object(Stripe_Util_Set)#109 (1) {
    ["_elts":"Stripe_Util_Set":private]=>
    array(0) {
    }
  }
  ["_transientValues":protected]=>
  object(Stripe_Util_Set)#110 (1) {
    ["_elts":"Stripe_Util_Set":private]=>
    array(0) {
    }
  }
  ["_retrieveOptions":protected]=>
  array(0) {
  }
}
Link to comment
Share on other sites

The question is how do you slice it?  I get an object and it, well, frankly is not my own.  Regardless of the API.  The structure could perhaps be salvaged into my API.  Especially important if we want to juggle the credit card opportunity -- sort of RolaDex the cards, as they are stored by the Stripe.com.

 

It is not difficult to execute financial transactions.  But when they are executed, some information (bare minimum) has to be recognized on the spot to substantiate the the transaction.

 

So here is what I have reduced the object structure to.  

 

mildly post-commented var_dumping:


//////forget the postjob, its all the same

/////$stripeid 
array(19) {
  ["id"]=>
  string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
  ["object"]=>
  string(6) "charge"
  ["created"]=>
  int(1394249960)
  ["livemode"]=>
  bool(false)
  ["paid"]=>
  bool(true)
  ["amount"]=>
  int(12200000)
  ["currency"]=>
  string(3) "usd"
  ["refunded"]=>
  bool(false)
  ["card"]=>
  string(29) "card_103cr12FbnVF9TNR87RIz7Z9"
  ["captured"]=>
  bool(true)
  ["balance_transaction"]=>
  string(28) "txn_103cr12FbnVF9TNRFCXP77yw"
  ["failure_message"]=>
  NULL
  ["failure_code"]=>
  NULL
  ["amount_refunded"]=>
  int(0)
  ["customer"]=>
  NULL
  ["invoice"]=>
  NULL
  ["description"]=>
  string(13) "write it NIKE"
  ["dispute"]=>
  NULL
  ["email"]=>
  string(26) "hatemail@hurtmail.com"
}

////////////$childs listed i++

array(20) {
  ["id"]=>
  string(29) "card_103cr12FbnVF9TNR87RIz7Z9"
  ["object"]=>
  string(4) "card"
  ["last4"]=>
  string(4) "4242"
  ["type"]=>
  string(4) "Visa"
  ["exp_month"]=>
  int(1)
  ["exp_year"]=>
  int(2045)
  ["fingerprint"]=>
  string(16) "UWeI9V7h9H0Arx76"
  ["customer"]=>
  NULL
  ["country"]=>
  string(2) "US"
  ["name"]=>
  string(17) "Barry Leibenstien"
  ["address_line1"]=>
  string(16) "125 North Street"
  ["address_line2"]=>
  string(12) "Second floor"
  ["address_city"]=>
  string( "New York"
  ["address_state"]=>
  string(2) "NY"
  ["address_zip"]=>
  string(5) "90210"
  ["address_country"]=>
  NULL
  ["cvc_check"]=>
  NULL
  ["address_line1_check"]=>
  string(4) "pass"
  ["address_zip_check"]=>
  string(4) "pass"
  ["charge"]=>
  string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
}
array(1) {
  ["charge"]=>
  string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
}
array(2) {
  ["email"]=>
  string(26) "hatemail@hurtmail.com"
  ["charge"]=>
  string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
}

/////////////dump childarray

array(1) {
  ["card"]=>
  string(29) "card_103cr12FbnVF9TNR87RIz7Z9"
}



//////////// this is the hit the DB takes

array(20) {
  ["id"]=>
  string(27) "ch_103cr12FbnVF9TNRrjH0A0VY"
  ["object"]=>
  string(6) "charge"
  ["created"]=>
  int(1394249960)
  ["livemode"]=>
  bool(false)
  ["paid"]=>
  bool(true)
  ["amount"]=>
  int(12200000)
  ["currency"]=>
  string(3) "usd"
  ["refunded"]=>
  bool(false)
  ["card"]=>
  string(29) "card_103cr12FbnVF9TNR87RIz7Z9"
  ["captured"]=>
  bool(true)
  ["balance_transaction"]=>
  string(28) "txn_103cr12FbnVF9TNRFCXP77yw"
  ["failure_message"]=>
  NULL
  ["failure_code"]=>
  NULL
  ["amount_refunded"]=>
  int(0)
  ["customer"]=>
  NULL
  ["invoice"]=>
  NULL
  ["description"]=>
  string(13) "write it NIKE"
  ["dispute"]=>
  NULL
  ["email"]=>
  string(26) "hatemail@hurtmail.com"
  ["timestamp"]=>
  string(23) "2014-03-07 22:39:20 EST"
}
Link to comment
Share on other sites

I pursued the documentation and gathered some of the clumpy stuff that may or may not lend itself to OO'd tooling in the future.





CHILDS
fee_details
cards
subscriptions
lines           invoice
created		List all Invoice, List all Customers, List all Application Fees, List balance history, List all events
date		List all Transfers -- like created
available_on		List balance history

refunds		charge
card		new charge, update customer, Creating a new card, The token object, Creating a Card Token, Creating a new charge , subscription

active_account		The recipient object

bank_account		Creating a New Recipient, The token object, Creating a Bank Account Token, Updating a recipient

data			The event object




EXPANDS
transaction x2 in charge obj
customer invoice
invoice
default_card customerobj
charge
date
account



OBJECT TYPES

list
card
charge
customer

Edited by Augury
Link to comment
Share on other sites

This is what I used to drag the object visibility down with.

 

Basically I want to record successful transactions.  These are important to me.  Information is an asset.  The more information I posses regarding a transaction and those involved the better.

 

stepwise:

  • create a stripe object with my post data.  a priori.
  • there is an error catch that will display the reason why the card transaction has not gone to completion.  The only trouble I've had so far is going forward and backward in my browser.  (and my bootstrap isn't jumping-to-it).  Stripe has JS which should curtail most of the errors prior to the attempt.
  • the strip object is internalized by the API and the object concept is removed.....we now have and array with the same structure (array keys may or may not nest other arrays) 

    $stripeobject = new Stripe_Object($chargeobj);

    $stripearray = $stripeobject->__toArray(true);

  • the nesting gets keyed up.

    the constraining priciple is that there are objects. these have types. the objects are contained as variables labeled with the original object type designation. The presence of a nested object is inserted into the parent array as $type => $id. The parent also has an id key and an object key which it retains.

    foreach($stripearray["id"] as $k=>$v) {

    if(is_array($v)) {

    $$k = $v;

    ${$k}[$stripearray["id"]["object"]] = $stripearray["id"]["id"];

    $childs[] = $k;

     

    if(isset($v["id"])) { $stripeid[$k] = $v["id"]; $childarray[$k] = $v["id"]; }

    else {

    foreach($v as $m=>$d)

    { $stripeid[$m] = $d; //$childarray[$m] = $d;

    }

    }

    }

    else

    {

    $stripeid[$k] = $v;

    }

    }

  • the children are probably worthless. they are retained in three ways. one by a list of keys => ids, two as independent arrays with the parent object contained therein (in the same way child objects are referenced in parent, the parent object is keyed less abstractly to the unique ID.)

    metadata and any data which does not have its own ID is simply unnested to be in the table row of the transaction.

  • The data is run over the database so as to succeed in record retention with less than 100% earnest. The data cutting can sized to the data handling undertook.

<?php

var_dump($_POST);

require_once('./stripe/Stripe.php');
require_once('./Member/Memberdb.php');
include('./common/Time.php');

$whitedevil = $_POST;
$_POST = NULL;

session_cache_limiter('private, must-revalidate');
if (!isset($_SESSION)) { session_start();}

Stripe::setApiKey("sk_test_wM8hH8PRkca2JUx5CUxo80FA");

 try {
$chargeobj = Stripe_Charge::create(array(
  "card" => array(
	"type" => 			$whitedevil['type'],
	"number" => 		$whitedevil['creditcard'],
	"exp_month" => 		$whitedevil['exp_month'],
	"exp_year" => 		$whitedevil['exp_year'],
	"cvc_check" => 		$whitedevil['cvv'],
	"name" => 			$whitedevil['bill_first_name'] . " " . $whitedevil['bill_last_name'],
	"address_line1" => 	$whitedevil['bill_address'],
	"address_line2" => 	$whitedevil['bill_addresstwo'],
	"address_city" => 	$whitedevil['bill_city'],
	"address_state" =>	$whitedevil['bill_state'],
	"address_zip" => 	$whitedevil['bill_zip']
	//"address_country" =>$whitedevil["bill_country"],
	),
//	"email" => 			$_SESSION["LI"]["email"],
	"currency" => "usd",
	"metadata" => array("SHAzAAAM" => "white devil"),
	"amount" => 12200000,
	"description" => "write it NIKE",
	"metadata" => array("email" => $_SESSION["LI"]["email"])
));
				} catch(Stripe_CardError $e) {
							echo "Since its a decline, Stripe_CardError will be caught";
							$body = $e->getJsonBody();
							$err  = $body['error'];
							print('Status is:' . $e->getHttpStatus() . "\n");
							print('Type is:' . $err['type'] . "\n");
							print('Code is:' . $err['code'] . "\n");
							// param is '' in this case
							print('Param is:' . $err['param'] . "\n");
							print('Message is:' . $err['message'] . "\n");
							if(isset($err['message'])) { $_SESSION['hasErr']['cc'] = $err['message']; var_dump($e);}
				} catch (Stripe_InvalidRequestError $e) {
							echo "Invalid parameters were supplied to Stripes API";
							if(isset($err['message'])) { $_SESSION['hasErr']['cc'] = $err['message']; }
				} catch (Stripe_AuthenticationError $e) {
							echo "Authentication with Stripes API failed (maybe you changed API keys recently)";
							if(isset($err['message'])) { $_SESSION['hasErr']['cc'] = $err['message']; }
				} catch (Stripe_ApiConnectionError $e) {
							echo "Network communication with Stripe failed";
				} catch (Stripe_Error $e) {
							echo "Display a very generic error to the user, and maybe send yourself an email";
				} catch (Exception $e) {echo "Something else happened, completely unrelated to Stripe"; 
							echo "Something else happened, completely unrelated to Stripe";  var_dump($e); }
				session_write_close();
				session_start();

			if(isset($e)) { header('location: ./buy.php'); exit(); }

//Stripe has not committed us yet

		$stripeobject = new Stripe_Object($chargeobj);

		$stripearray = $stripeobject->__toArray(true);

var_dump($stripeobject);
var_dump($stripearray);

		foreach($stripearray["id"] as $k=>$v) {
			if(is_array($v)) {
				$$k = $v;
				${$k}[$stripearray["id"]["object"]] = $stripearray["id"]["id"];
				$childs[] = $k;
				
					if(isset($v["id"]))  { $stripeid[$k] = $v["id"]; $childarray[$k] = $v["id"]; }
					else {
						foreach($v as $m=>$d)
							{ $stripeid[$m] = $d; //$childarray[$m] = $d;
							}
					}
			}
			else
			{
				$stripeid[$k] = $v;
			}
		}
	
echo "stripeid dump";
		
var_dump($stripeid);
echo "for(i=0;i<count(childarrays);i++) { var_dumpchildarrays[i]); } dump";
		
		for($i=0;$i<count($childs);$i++) { var_dump(${$childs[$i]}); }
echo "dump childarray";
var_dump($childarray);


	if($stripearray["id"]['paid'] === TRUE) {

			$DBO = array_merge($stripeid, Time::Stamp('EST'), array("email"=>$_SESSION["LI"]["email"]));
			var_dump($DBO);
			
			$cdb = new crud;
			$cdb->dbInsertArray('StripeTxn', $DBO);
			
			include('ordercomplete.php'); exit;
		} else {
			foreach($whitedevil as $f => $p) {
				$_SESSION['ccfields'][$f] = $whitedevil[$p];
			}
			include('buysomething.php');
		}
?> 


Link to comment
Share on other sites

This is the crud function the array conglomerate is sent to.



 public function dbInsertArray($table, $ray, $fsvlevel = 'no') {
	$this->conn();
	$sth = $this->db->prepare("SELECT member_keys, formsubmit FROM AtributesT;");
	$sth->execute();
	$sth->bindColumn('member_keys', $memkey);
	$sth->bindColumn('formsubmit', $fsv);
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) { $formsubmit[$memkey] = $fsv;}

		$sth = $this->db->prepare("SHOW COLUMNS FROM $table;");
		$sth->execute();
		$sth->bindColumn('Field', $flds);
		while ($row = $sth->fetch(PDO::FETCH_BOUND)) { 
			if (!empty($ray[$flds]) && ($formsubmit[$flds] !== "no")) {
				$insert[] = $ray[$flds];
				$ptsd[] = $flds;
				$q[] = "?";
			}}
		$sql = 'INSERT INTO ' . $table . ' (' . implode(", ", $ptsd) . ') VALUES (' . implode(", ", $q) . ');';
	var_dump($sql);
		$dbin = $this->db->prepare($sql);
		$dbin->execute(array_values($insert));
}
Link to comment
Share on other sites

The PHP concepts use are array and all functions pertaining to arrays "array reference".

 

"Variable Variables", used to arbitrarily provide a common name to the nested object.

 

Stripe API 1.11.0.  They assure us that they do not develop like teenage girls -- this is the output. mv ./lib ./stripe and loads itself (its not a lib, hu).  Its convoluted.  Important files are Object.php, grep's for parent error classes, the documentation dictates the call.

 

"crud" database functions.  google for a blank and edit as needed.  here is mine

<?php

class crud
{
	private $db;

 public function __set($name, $value) {
	switch($name) {
		case 'username':
		$this->username = $value;
		break;
		case 'password':
		$this->password = $value;
		break;
		case 'dsn':
		$this->dsn = $value;
		break;
		default:
		throw new Exception("$name is invalid");
	}
}

 public function conn() {
	$username = 'root';
	$password = 'define ~ CukHenpooker WAH ';
	$dsn = 'mysql:host=localhost;dbname=MemberDB';
	if (!$this->db instanceof PDO)
	{
			$this->db = new PDO($dsn, $username, $password);
			$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	}
}

 public function rawSelect($sql) {
	$this->conn();
	return $this->db->query($sql);
}

 public function rawQuery($sql) {
	$this->conn();
	$this->db->query($sql);
}

 public function dbFields ($table) {
	$sth = $this->db->prepare("SHOW COLUMNS FROM " . $table . ";");
	$sth->execute();
	$sth->bindColumn('Field', $flds);
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) { 
		$fields[] = $flds;
	}
	return $fields;
}
 public function dbFFields ($table, $restict = NULL, $restricttwo = NULL) {
	$sth = $this->db->prepare("SELECT member_keys, formsubmit FROM AtributesT;");
	$sth->execute();
	$sth->bindColumn('member_keys', $memkey);
	$sth->bindColumn('formsubmit', $fsv);
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) { $formsubmit[$memkey] = $fsv;}

	$sth = $this->db->prepare("SHOW COLUMNS FROM " . $table . ";");
	$sth->execute();
	$sth->bindColumn('Field', $flds);
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) {
		if(($formsubmit[$flds] !== "no") && ($formsubmit[$flds] !== $restrict) && ($formsubmit[$flds] !== $restricttwo)) {
		$fields[] = $flds;
		}

	}
	return $fields;
}

 public function dbSelect($table, $fieldname=null, $id=null) {
	$this->conn();
	$sql = "SELECT * FROM `$table` WHERE `$fieldname`=:id";
	$stmt = $this->db->prepare($sql);
	$stmt->bindParam(':id', $id);
	$stmt->execute();
	$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
	return $row;
}

 public function dbInsertArray($table, $ray, $fsvlevel = 'no') {
	$this->conn();

	$sth = $this->db->prepare("SELECT member_keys, formsubmit FROM AtributesT;");
	$sth->execute();
	$sth->bindColumn('member_keys', $memkey);
	$sth->bindColumn('formsubmit', $fsv);
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) { $formsubmit[$memkey] = $fsv;}

		$sth = $this->db->prepare("SHOW COLUMNS FROM $table;");
		$sth->execute();
		$sth->bindColumn('Field', $flds);
		while ($row = $sth->fetch(PDO::FETCH_BOUND)) { 
			if (!empty($ray[$flds]) && ($formsubmit[$flds] !== "no")) {
				$insert[] = $ray[$flds];
				$ptsd[] = $flds;
				$q[] = "?";
			}}
		$sql = 'INSERT INTO ' . $table . ' (' . implode(", ", $ptsd) . ') VALUES (' . implode(", ", $q) . ');';
	var_dump($sql);
		$dbin = $this->db->prepare($sql);
		$dbin->execute(array_values($insert));
}

 public function dbInsert($table, $values) {
	$this->conn();
	$fieldnames = array_keys($values[0]);
	$size = sizeof($fieldnames);
	$i = 1;
	$sql = "INSERT INTO $table";
	$fields = '( ' . implode(' ,', $fieldnames) . ' )';
	$bound = '(:' . implode(', :', $fieldnames) . ' )';
	$sql .= $fields.' VALUES '.$bound;
	$stmt = $this->db->prepare($sql);
	foreach($values as $vals) {
			$stmt->execute($vals);
	}
}

 public function dbUpdate($table, $fieldname, $value, $pk, $id) {
	$this->conn();
	$sql = "UPDATE `$table` SET `$fieldname`='{$value}' WHERE `$pk` = :id";
	$stmt = $this->db->prepare($sql);
	$stmt->bindParam(':id', $id, PDO::PARAM_STR);
	$stmt->execute();
}

 public function dbAtributes($atribute) {
	$sth = $this->db->prepare("SELECT member_keys, ". $atribute . " FROM AtributesT;");
	$sth->execute();
	$sth->bindColumn('member_keys', $memkey);
	$sth->bindColumn($atribute, $atr);
	$req = array();
	while ($row = $sth->fetch(PDO::FETCH_BOUND)) { $atributes[$memkey] = $atr; }
	return $atributes;
}

 public function dbDelete($table, $fieldname, $id) {
	$this->conn();
	$sql = "DELETE FROM `$table` WHERE `$fieldname` = :id";
	$stmt = $this->db->prepare($sql);
	$stmt->bindParam(':id', $id, PDO::PARAM_STR);
	$stmt->execute();
}

}///////END CLASS



 /*public function __isset($name, $value) {
	//$username = 'root';
	//$password = 'Uluuka ~ CHeEk1nfOkr WAH ';
	//$dsn = 'MemberDB';

	switch($name) {
		case 'username':
		$this->username = 'root';
		break;
		case 'password':
		$this->password = 'CHeekinfOkr WAH';
		break;
		case 'dsn':
		$this->dsn = 'MemberDB';
		break;
		default:
		throw new Exception("$name is invalid");
	}
}
 public function __construct() {
	$username = 'root';
	$password = 'define ~ kEEkinfeekr WAH ';
	$dsn = 'MemberDB';
}*/

?>



Link to comment
Share on other sites

you'll need a database relevant for the crud to do

 

to NULL or not to NULL?  I don't know.  The recommendation is utf8-bin collation.  That needs to be added to this sql.  Else it will do something,



CREATE TABLE `StripeTxn` (
`TID` int(6) AUTO_INCREMENT,
`timestamp` CHAR(255) DEFAULT "",
`XMemberDB` CHAR(255) DEFAULT "",
`XOrdersDB` CHAR(255) DEFAULT "",
`XAccountsDB` CHAR(255) DEFAULT "",
`XLocationsDB` CHAR(255) DEFAULT "",
`XJLLinDB` CHAR(255) DEFAULT "",
`account_balance` CHAR(255) DEFAULT "",
`address_city` CHAR(255) DEFAULT "",
`address_country` CHAR(255) DEFAULT "",
`address_line1` CHAR(255) DEFAULT "",
`address_line1_check` CHAR(255) DEFAULT "",
`address_line2` CHAR(255) DEFAULT "",
`address_state` CHAR(255) DEFAULT "",
`address_zip` CHAR(255) DEFAULT "",
`address_zip_check` CHAR(255) DEFAULT "",
`amount` CHAR(255) DEFAULT "",
`amount_refunded` CHAR(255) DEFAULT "",
`balnce_transaction` CHAR(255) DEFAULT "",
`captured` CHAR(255) DEFAULT "",
`card` CHAR(255) DEFAULT "",
`cards` CHAR(255) DEFAULT "",
`count` CHAR(255) DEFAULT "",
`country` CHAR(255) DEFAULT "",
`created` CHAR(255) DEFAULT "",
`currency` CHAR(255) DEFAULT "",
`customer` CHAR(255) DEFAULT "",
`cvc_check` CHAR(255) DEFAULT "",
`data` CHAR(255) DEFAULT "",
`default_card` CHAR(255) DEFAULT "",
`delinquent` CHAR(255) DEFAULT "",
`description` CHAR(255) DEFAULT "",
`discount` CHAR(255) DEFAULT "",
`dispute` CHAR(255) DEFAULT "",
`email` CHAR(255) DEFAULT "",
`exp_month` CHAR(255) DEFAULT "",
`exp_year` CHAR(255) DEFAULT "",
`failure_code` CHAR(255) DEFAULT "",
`failure_message` CHAR(255) DEFAULT "",
`fingerprint` CHAR(255) DEFAULT "",
`id` CHAR(255) DEFAULT "",
`invoice` CHAR(255) DEFAULT "",
`last4` CHAR(255) DEFAULT "",
`livemode` CHAR(255) DEFAULT "",
`metadata` CHAR(255) DEFAULT "",
`name` CHAR(255) DEFAULT "",
`object` CHAR(255) DEFAULT "",
`paid` CHAR(255) DEFAULT "",
`refunded` CHAR(255) DEFAULT "",
`refunds` CHAR(255) DEFAULT "",
`subscriptions` CHAR(255) DEFAULT "",
`type` CHAR(255) DEFAULT "",
`url` CHAR(255) DEFAULT "",
 PRIMARY KEY (`TID`)
	) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

can add ENGINE=MyISAM

 

this DB SQL has internal relational fields (X) and fields common to stripe.  conflicts may exist.

 

It does not translate anything involving lists and such.

 

echo reporting a missing field in the crud would provide relevant information regarding absent columns.

 

you will want add the unique Member ID as well the X'ID relations.

 

Stripe bogarts the id field so table-self-specific ids are TID.

Edited by Augury
Link to comment
Share on other sites

The use of AttributesT is rather last resort in the crud.  This is only providing for external administration field protection.  it works as such, The columns of the DB tables have row entries *as if they were data*.  The columns are the attributes a field may posses.  Fields are of course common amongst databases so an attribute table is only a good as field which is not overloaded and the extent to which you are willing to queery.  AttributesX provides the criteria for table intersection.

 

The rational for AttributesT and AttributesX is that regardless of the HTML provided to a user, any data may be posted to a website whatsoever.  This would be achieved through any number of methods, including those belonging to the site itself.  Therefore it is necessary to prevent -- off the bat --  things such as posting ["paid"] boolean true.  And it may as well be true, so AttributesT might extend 100 columns to cover more and more situations.  Ease of implementation is what is important.  In design, we would want to assume one perspective, then with a list of fields we would want to define that perspective -- like a document with information blacken out and then xerox'd.  More perspectives place emphasis on given definitions.  Bitmasks are tempting but 14 pages of check y or n is just tedious.  10 pages of consecutive bimask calculation is not feasible from a practical standpoint.

Link to comment
Share on other sites

30,604 posts.  um.

 

Yeah.  What do you think?  Methodology too risqué?

 

Compared to PayPal, PayPal has features such as the ability to prevent x2 charges.  x2 charges is probably the #1 issue when dealing with CC charges -- from a back office stand point.  Most merchants are just anal with the thing . . . see you would know when and where this occurs because it has in the past, obviously the system has it failings.

 

. . . on the internet however the customer submits for the charge.  Dealing with this:

 

  • javascript does the typo handling
  • we hammer throw the charge and send the customer to a page that will lead the customer elsewhere

What we need now is a means of preventing the customer from resubmitting information.  This is probably going to be session field NULL' in the the pay success page.  And we leave it at that.  If the customer truly wants to make consecutive payments, customer must enter 19 digits at the least.

Link to comment
Share on other sites

But then when a browser recedes in the page history, it wants to fill in fields.  There is a strong possibility that it WILL leave the fields filled in.

 

To prevent the payment system from making a transaction we want to queery this specific order for $paid === true.

 

If it hasn't been paid, there is solid rational for the customer to resubmit the form and we would like the payment to only succeed in this case.

Link to comment
Share on other sites

Anyways, the PayPal API suffers from a lack of coordinated package handling.

 

Just because it works in one location does not, by any means, guarantee that ship will sail given water to float in.

 

Stripe is loaded with a single file in the stripe directory (it was lib directory if you were not paying attention).  Above the stripe directory there are two directories, one of them is just there for being deleted.

 

I personally use the lower directory for any stripe related stuff I have.

 

The stripe Object dump isn't real feature forward.  The only concern I had was handling it on point.  Fortunately there isn't much other than making money that we want to do.

 

Stripe has a dashboard BTW where refunds can be issued.  It's sort of imperative that the original transaction is at least recorded, however, because they do not really sus the data much beyond the cryptic index handles.  And it is sort of slow.

Link to comment
Share on other sites

Wait, its needs a form.





<?php
	require_once('buy.php');
	require_once('./Member/Memberdb.php');
	require_once("./PFBC/Form.php");
	include("header.php");
	
	use PFBC\Form;
	use PFBC\Element;

	session_cache_limiter('private, must-revalidate');
	if (!isset($_SESSION)) { session_start();}

		$email = $_SESSION["LI"]["email"];
		$cdb = new crud;
		$member = $cdb->dbSelect('MemberT', 'email', $email);
?>
			<!DOCTYPE html>
			<html lang="en">
	<head>
			<meta http-equiv="content-type" content="text/html; charset=UTF-8" >
			<meta name="viewport" content="width=device-width, initial-scale=1.0">

		<title>Card Payment</title>


		<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
		<link type="text/css" rel="stylesheet" href="./css/normalize.css">
		<!--<link href="./prettify/prettify.css" rel="stylesheet"> -->

		<!--<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js"></script>
		<link type="text/css" rel="stylesheet" href="./css/cat.css">-->

		<!--<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
		<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
		<!--<script type="text/javascript" src="./prettify/prettify.js"></script>-->
		<!--<script type="text/javascript" src="https://js.stripe.com/v1/"></script>-->

	<script type="text/javascript">
		function copyBilling (f) {
			var s, i = 0;
			while (s = ['first_name', 'last_name', 'address', 'addresstwo', 'city', 'state', 'zip'][i++]) {
				if (f.elements['bill_' + s].value == "") {
					f.elements['bill_' + s].value = f.elements['user_' + s].value;
				}
			};
		}
	</script>

	<script type="text/javascript">
	jQuery(document).ready(function() {
		jQuery("#creditcardtxn").bind("submit", function() {
			jQuery(this).find("input[type=submit]").attr("disabled", "disabled");
		});
		jQuery("#creditcardtxn :input:visible:enabled:first").focus();
	});
	</script>

	<style type="text/css">
		legend {
			text-align: center;
			padding-left: 6em;
		}
		body {
			padding-top: 16px;
			padding-bottom: 20px;
		}
		.sidebar-nav {
			padding: 9px 0;
		}
	</style>

	<style type="text/css">label span.required { color: #B94A48; }span.help-inline, span.help-block { color: #888; font-size: 1em; font-style: italic; }</style>

</head>


	<body>
		<div class="col-xs-12 col-xs-push-0 col-xs-pull-6">

			<form name="creditcardtxn" id="creditcardtxn" action="./ppstart3.php" method="post" class="form-horizontal">
			<!--<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" onsubmit="total (this)" method="post" class="form-horizontal">  -->
				<fieldset>
					<legend>Billing Address</legend><br/>
					<label>First Name<input class="form-control" type="text" name="user_first_name" SIZE=18 value="<?php if(isset($member[0]['first_name'])) echo $member[0]['first_name'];?>" readonly></label>
					<label>Last Name<input class="form-control" type="text" name="user_last_name" SIZE=18 value="<?php if(isset($member[0]['last_name'])) echo $member[0]['last_name'];?>"></label>
					<br/><label>Address<input class="form-control" type="text" name="user_address" SIZE=30 value="<?php if(isset($member[0]['address'])) echo $member[0]['address'];?>"></label>
					<br/><label>Address two<input class="form-control" type="text" name="user_addresstwo" SIZE=30 value="<?php if(isset($member[0]['addresstwo'])) echo $member[0]['addresstwo'];?>"></label>
					<br/><label>City<input class="form-control" type="text" name="user_city" SIZE=20 value="<?php if(isset($member[0]['city'])) echo $member[0]['city'];?>"></label>
					<label>State<input class="form-control" type="text" name="user_state" SIZE=2 value="<?php if(isset($member[0]['state'])) echo $member[0]['state'];?>"></label>
					<label>Zip Code<input class="form-control" type="text" name="user_zip" SIZE=10 value="<?php if(isset($member[0]['zip'])) echo $member[0]['zip'];?>"></label>
				</fieldset>

				<br/><br/>

				<fieldset>
					<legend>Shipping Address</legend><br/>
					<label style="padding-left: 5.55em; padding-right: 3 em; text-align: left;">Fill in the Blanks <input name="same" onclick="if (this.checked) copyBilling (this.form)" type="checkbox"></label><br />
					<label>First Name <input class="form-control" type="text" name="bill_first_name" SIZE=18></label>
					<label>Last Name <input class="form-control" type="text" name="bill_last_name" SIZE=18></label>
					<br/><label>Address <input class="form-control" type="text" name="bill_address" SIZE=30></label>
					<br/><label>Address line two <input class="form-control" type="text" name="bill_addresstwo" SIZE=30></label>
					<br/><label>City <input class="form-control" type="text" name="bill_city" SIZE=20></label>
					<label>State <input class="form-control" type="text" name="bill_state" SIZE=2></label>
					<label>Zip Code <input class="form-control" type="text" name="bill_zip" SIZE=10></label> 
				</fieldset>

				<br/><br/>

	<fieldset> <legend>Payment Information</legend> <label>Credit Card:<fieldset></label>

				<?php
				if(!empty($_SESSION['hasErr']['cc'])) { 
					echo '<div class="alert alert-danger">
								<button type="button" class="close" data-dismiss="alert" aria-hidden="false">×</button>
								<strong class="alert-heading">The Credit Card entry cannot process:</strong>
								<ul><li>';
  					echo $_SESSION['hasErr']['cc']; $_SESSION['hasErr']['cc'] = "";
  					echo '</li></ul>
					</div>';
				}
				?>
				<label>Credit Card Number<input class="form-control" type="text" SIZE=19 value="4242424242424242" name="creditcard"></label>
				<label>Credit Card Type <select class="form-control" name="type">

					<?php
					$cctypes = array("mastercard"=>"Master Card", "visa"=>"Visa", "amex"=>"American Express");
					foreach($cctypes as $val=>$name) {
						if(isset($cctype) && ($cctype == $val)) {
							echo " <option value='" . $val. "'selected>" . $name . "</option>"; }
						else {
							echo " <option value=" . $val . ">" . $name . "</option>"; }
						}
					?>
					</select></label>
					
					
					<div class="row">
					<label><div class="col-xs-12">Card Expires:</div>
					</label>
					</div>
					<div class="row">
					<div class="col-xs-8">
					<label><input class="form-control" type="text" name="exp_month" SIZE=2>month</label>/
					<label><input class="form-control" type="text" name="exp_year" SIZE=4>year</label>
					</div>
					<div class="col-xs-4">
					<label><input class="form-control" type="text" name="cvv" SIZE=3>CVV</label>
					</div>
					</div>
					</fieldset>
				<span class="help-block">CVV/CVC 3 digit security code on back of card</span>
				<input  type="submit" value="Submit" class="btn btn-primary " name="submitbillinfo" id="submitbillinfo"/>
				<input  type="button" value="Cancel" class="btn btn-default" name="cancelbillinfo" onclick="history.go(-1);" id="cancelbillinfo"/>
	</fieldset>
			</form>
		</div>
	</body>
</html>


<?php
	if ($_SERVER["REQUEST_METHOD"] == "POST") {
		$_SESSION['hasErr']['cc'] = "";
	}
?>





<?php
//buy.php
	session_cache_limiter('private, must-revalidate');

	if (!isset($_SESSION)) { session_start();}

	if(isset($_SESSION['LI'])) { if($_SESSION['LI']["isloggedin"]=="IS") {
		include("buysomething.php");
		//header("Location: loggedin.php");
	} else {
		header("Location: index.php");
		include("login.php");
	}} else {include("login.php"); header("Location: index.php");}
?>

I don't know why it's in two files.  What it needs is a lock and unlock upon return on the order at which point I'm thinking it should be locked again.  It runs in about 3/4's of a second.  The order might get you locked out, so after about 5 seconds you should be able to unlock it load the form but lock it first.  You also need a page for the successful payment of an order.

 

You can lock the thread now because obviously no one wants to answer my question.

Edited by Augury
Link to comment
Share on other sites

  • Solution

Well what situations could result from a credit card transaction?  What are the security issues?

 

First im saying, I've done credit card business via websites and I have not had the "5 9's" success as a consumer (99.999%).  There are a myriad of reasons why.  My last transaction, yesterday, I was registering a vehicle online..  It took 4 trys on the credit card information, once again.  It seems as if, I, a frequent internet shopper still has not learned how to fill in a simple form.  Whats more the whole site was depressingly ugly throughout the process upto the radio organ donor awareness fund requirement.  This is a transaction I put off a bit, but I also consider this one of the easier transaction that I make.

 

Not providing shipping information with a zip is cause for me to skip a site but I am frugal.

 

But downright have a card fail and not receiving a viola response, rather something that just came to me in the mail, maybe -- even some of the best and most trusted sites this occurs.  Three days out, how about that order?  Hey tell me now, fuckyou.  Like I said I'm a 50% chance on those fields.  But I might be dealing with 5 cards, two business addresses, mailing address, god only knows there isn't money in that account or where it is billed to, and a $3000 dollar order that took me a hour to get together.

 

So I like I sort of prefer that the order at least gives me a second, third and fourth try.  I know I shouldn't do it but it happens.

 

I'm a weird customer.  I know what I want and I have the wherewithall to get it.  Most customers are not like me.  Their aggression is not positive and they probably have a sort of a little reputation to up hold as not doing nefarious business.  They also do not want to spend much time doing the business, although it is possible to capture them for brief amount of time.  Certainly do not want it to be questioned.

 

Having been charged twice is not the most critical issue for them but it costs a lot in the long run.  Its usually sun spots.

 

SO back to the situations that may arise.  It's the question.

 

One, the customer is literate and is able to correctly key in CC number the first time.  The expiration date is correct and so on, Success.

 

Two the customer is not thinking completely level and miss keys the information, user may have accessibility issues.  The browser has to return on its own to the form page.  The customer might then use the back button for whatever reason.  The same incorrect information should be there and so X2 charging should not occur.

 

Three,  the submit is sent off and there is but no reply.  And now we have about a 75% chance of having lost the customer due to a lack of communication.  It so happens that people with money like to fuck with you, so we might haven gotten away with this one more time but it looks like, mmm?  Any email at?  Order might be there?  There just isn't a personality type that won't say "I hit submit...".  Not one.  Not in the USA.  In a way this in itself is a form of X2 charge protection.

 

Four, the customer needs to reload the the order if it is still possible.  If that order is not in existence any longer the order will be recreated.  Now the customer has two orders coming his way?  hmm.  Large orders, especially non-returnables, kind of a boo boo.

 

Five the site is in the opinion of the user impossible or impractical.  Anyways they leave and will probably avoid the site for the rest of their lives.  Learning.

 

 

 

In Reviewing

 

 

It seems as though the paradigms of internet transactions are not something we want to replicate.  The proposition of using javascript is going to have to be out of the question due to potential load glitches.  For some reason my mobile progress bar goes out 50% and then does something else regardless of connection speed.  Which means a user who make little errors is going to have, mmm, like 10, 15, 45 seconds to wait regardless of the page size.  I know it would be a miracle if IE8 were to navigate to my website, but I think in some instances the javascipts all in all just don't work.

 

So boostrap yes, or, bootstrap no?  I'll tell you I might have less than ten customers.  The bootsrap look real good and professional enough-ish.  It can be crisped up some.  Those ten customers will probably be much more enthusiastic to return.

 

 

Maybe it's not the javascript.  Maybe the breve time out the browser spins on is enough to qualify a incomplete connection state which can no longer be reconnected.  In the instance of wifi, the connection may be lost completely for some period of time.

 

 

Email confirmation is always nice.  Of course we should email confirm.  Leave the emails.

 

Card storage is good, provided my time is not wasted.  They say "don't keep users CC number on the data base".  Hmm.  Take the credit and leave for 15 minutes.  Come back with a really big smile.  ?  Hopefully you don't have orders that are all priced identically.  Very, very personal about the card thing.  Take the credit and leave for 15 minutes.  Come back and say you lost it but if you give me another one I can use it.  ?

 

OK I said I don't want to replicate a system of mistakes, but what are the industry standards exactly?  Who writes this shit?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.