MS_Gateway_Stripe

Stripe Gateway Integration.

Defined (1)

The class is defined in the following location(s).

/app/gateway/stripe/class-ms-gateway-stripe.php  
  1. class MS_Gateway_Stripe extends MS_Gateway { 
  2.  
  3. const ID = 'stripe'; 
  4.  
  5. /** 
  6. * Gateway singleton instance. 
  7. * @since 1.0.0 
  8. * @var string $instance 
  9. */ 
  10. public static $instance; 
  11.  
  12. /** 
  13. * Stripe test secret key (sandbox). 
  14. * @see https://support.stripe.com/questions/where-do-i-find-my-api-keys 
  15. * @since 1.0.0 
  16. * @var string $test_secret_key 
  17. */ 
  18. protected $test_secret_key = ''; 
  19.  
  20. /** 
  21. * Stripe Secret key (live). 
  22. * @since 1.0.0 
  23. * @var string $secret_key 
  24. */ 
  25. protected $secret_key = ''; 
  26.  
  27. /** 
  28. * Stripe test publishable key (sandbox). 
  29. * @since 1.0.0 
  30. * @var string $test_publishable_key 
  31. */ 
  32. protected $test_publishable_key = ''; 
  33.  
  34. /** 
  35. * Stripe publishable key (live). 
  36. * @since 1.0.0 
  37. * @var string $publishable_key 
  38. */ 
  39. protected $publishable_key = ''; 
  40.  
  41. /** 
  42. * Instance of the shared stripe API integration 
  43. * @since 1.0.0 
  44. * @var MS_Gateway_Stripe_Api $api 
  45. */ 
  46. protected $_api = null; 
  47.  
  48. /** 
  49. * Initialize the object. 
  50. * @since 1.0.0 
  51. * @internal 
  52. */ 
  53. public function after_load() { 
  54. parent::after_load(); 
  55. $this->_api = MS_Factory::load( 'MS_Gateway_Stripe_Api' ); 
  56.  
  57. $this->id = self::ID; 
  58. $this->name = __( 'Stripe Single Gateway', 'membership2' ); 
  59. $this->group = 'Stripe'; 
  60. $this->manual_payment = true; // Recurring billed/paid manually 
  61. $this->pro_rate = true; 
  62.  
  63. /** 
  64. * Processes purchase action. 
  65. * @since 1.0.0 
  66. * @api 
  67. * @param MS_Model_Relationship $subscription The related membership relationship. 
  68. */ 
  69. public function process_purchase( $subscription ) { 
  70. $success = false; 
  71. $note = ''; 
  72. $token = ''; 
  73. $external_id = ''; 
  74. $error = false; 
  75.  
  76. do_action( 
  77. 'ms_gateway_stripe_process_purchase_before',  
  78. $subscription,  
  79. $this 
  80. ); 
  81. $this->_api->set_gateway( $this ); 
  82.  
  83. $member = $subscription->get_member(); 
  84. $invoice = $subscription->get_current_invoice(); 
  85.  
  86. if ( ! empty( $_POST['stripeToken'] ) ) { 
  87. lib3()->array->strip_slashes( $_POST, 'stripeToken' ); 
  88.  
  89. $token = $_POST['stripeToken']; 
  90. $external_id = $token; 
  91. try { 
  92. $customer = $this->_api->get_stripe_customer( $member, $token ); 
  93.  
  94. if ( 0 == $invoice->total ) { 
  95. // Free, just process. 
  96. $invoice->changed(); 
  97. $success = true; 
  98. $note = __( 'No payment for free membership', 'membership2' ); 
  99. } else { 
  100. // Send request to gateway. 
  101. $charge = $this->_api->charge( 
  102. $customer,  
  103. $invoice->total,  
  104. $invoice->currency,  
  105. $invoice->name 
  106. ); 
  107.  
  108. if ( true == $charge->paid ) { 
  109. $invoice->pay_it( $this->id, $charge->id ); 
  110. $note = __( 'Payment successful', 'membership2' ); 
  111. $note .= ' - Token: ' . $token; 
  112. $success = true; 
  113. } else { 
  114. $note = __( 'Stripe payment failed', 'membership2' ); 
  115. } catch ( Exception $e ) { 
  116. $note = 'Stripe error: '. $e->getMessage(); 
  117. MS_Model_Event::save_event( MS_Model_Event::TYPE_PAYMENT_FAILED, $subscription ); 
  118. MS_Helper_Debug::log( $note ); 
  119. $error = $e; 
  120. } else { 
  121. $note = 'Stripe gateway token not found.'; 
  122. MS_Helper_Debug::log( $note ); 
  123.  
  124. do_action( 
  125. 'ms_gateway_transaction_log',  
  126. self::ID, // gateway ID 
  127. 'process', // request|process|handle 
  128. $success, // success flag 
  129. $subscription->id, // subscription ID 
  130. $invoice->id, // invoice ID 
  131. $invoice->total, // charged amount 
  132. $note, // Descriptive text 
  133. $external_id // External ID 
  134. ); 
  135.  
  136. if ( $error ) { 
  137. throw $e; 
  138.  
  139. return apply_filters( 
  140. 'ms_gateway_stripe_process_purchase',  
  141. $invoice,  
  142. $this 
  143. ); 
  144.  
  145. /** 
  146. * Request automatic payment to the gateway. 
  147. * @since 1.0.0 
  148. * @api 
  149. * @param MS_Model_Relationship $subscription The related membership relationship. 
  150. * @return bool True on success. 
  151. */ 
  152. public function request_payment( $subscription ) { 
  153. $was_paid = false; 
  154. $note = ''; 
  155. $external_id = ''; 
  156.  
  157. do_action( 
  158. 'ms_gateway_stripe_request_payment_before',  
  159. $subscription,  
  160. $this 
  161. ); 
  162. $this->_api->set_gateway( $this ); 
  163.  
  164. $member = $subscription->get_member(); 
  165. $invoice = $subscription->get_current_invoice(); 
  166.  
  167. if ( ! $invoice->is_paid() ) { 
  168. try { 
  169. $customer = $this->_api->find_customer( $member ); 
  170.  
  171. if ( ! empty( $customer ) ) { 
  172. if ( 0 == $invoice->total ) { 
  173. $invoice->changed(); 
  174. $success = true; 
  175. $note = __( 'No payment for free membership', 'membership2' ); 
  176. } else { 
  177. $charge = $this->_api->charge( 
  178. $customer,  
  179. $invoice->total,  
  180. $invoice->currency,  
  181. $invoice->name 
  182. ); 
  183. $external_id = $charge->id; 
  184.  
  185. if ( true == $charge->paid ) { 
  186. $was_paid = true; 
  187. $invoice->pay_it( $this->id, $external_id ); 
  188. $note = __( 'Payment successful', 'membership2' ); 
  189. } else { 
  190. $note = __( 'Stripe payment failed', 'membership2' ); 
  191. } else { 
  192. $note = "Stripe customer is empty for user $member->username"; 
  193. MS_Helper_Debug::log( $note ); 
  194. } catch ( Exception $e ) { 
  195. $note = 'Stripe error: '. $e->getMessage(); 
  196. MS_Model_Event::save_event( MS_Model_Event::TYPE_PAYMENT_FAILED, $subscription ); 
  197. MS_Helper_Debug::log( $note ); 
  198. } else { 
  199. // Invoice was already paid earlier. 
  200. $was_paid = true; 
  201. $note = __( 'Invoice already paid', 'membership2' ); 
  202.  
  203. do_action( 
  204. 'ms_gateway_transaction_log',  
  205. self::ID, // gateway ID 
  206. 'request', // request|process|handle 
  207. $was_paid, // success flag 
  208. $subscription->id, // subscription ID 
  209. $invoice->id, // invoice ID 
  210. $invoice->total, // charged amount 
  211. $note, // Descriptive text 
  212. $external_id // External ID 
  213. ); 
  214.  
  215. do_action( 
  216. 'ms_gateway_stripe_request_payment_after',  
  217. $subscription,  
  218. $was_paid,  
  219. $this 
  220. ); 
  221.  
  222. return $was_paid; 
  223.  
  224. /** 
  225. * Get Stripe publishable key. 
  226. * @since 1.0.0 
  227. * @api 
  228. * @return string The Stripe API publishable key. 
  229. */ 
  230. public function get_publishable_key() { 
  231. $publishable_key = null; 
  232.  
  233. if ( MS_Gateway::MODE_LIVE == $this->mode ) { 
  234. $publishable_key = $this->publishable_key; 
  235. } else { 
  236. $publishable_key = $this->test_publishable_key; 
  237.  
  238. return apply_filters( 
  239. 'ms_gateway_stripe_get_publishable_key',  
  240. $publishable_key 
  241. ); 
  242.  
  243. /** 
  244. * Get Stripe secret key. 
  245. * @since 1.0.0 
  246. * @internal The secret key should not be used outside this object! 
  247. * @return string The Stripe API secret key. 
  248. */ 
  249. public function get_secret_key() { 
  250. $secret_key = null; 
  251.  
  252. if ( MS_Gateway::MODE_LIVE == $this->mode ) { 
  253. $secret_key = $this->secret_key; 
  254. } else { 
  255. $secret_key = $this->test_secret_key; 
  256.  
  257. return apply_filters( 
  258. 'ms_gateway_stripe_get_secret_key',  
  259. $secret_key 
  260. ); 
  261.  
  262. /** 
  263. * Verify required fields. 
  264. * @since 1.0.0 
  265. * @api 
  266. * @return boolean True if configured. 
  267. */ 
  268. public function is_configured() { 
  269. $key_pub = $this->get_publishable_key(); 
  270. $key_sec = $this->get_secret_key(); 
  271.  
  272. $is_configured = ! ( empty( $key_pub ) || empty( $key_sec ) ); 
  273.  
  274. return apply_filters( 
  275. 'ms_gateway_stripe_is_configured',  
  276. $is_configured 
  277. ); 
  278.  
  279. /** 
  280. * Auto-update some fields of the _api instance if required. 
  281. * @since 1.0.0 
  282. * @internal 
  283. * @param string $key Field name. 
  284. * @param mixed $value Field value. 
  285. */ 
  286. public function __set( $key, $value ) { 
  287. switch ( $key ) { 
  288. case 'test_secret_key': 
  289. case 'test_publishable_key': 
  290. case 'secret_key': 
  291. case 'publishable_key': 
  292. $this->_api->$key = $value; 
  293. break; 
  294.  
  295. if ( property_exists( $this, $key ) ) { 
  296. $this->$key = $value;