Invision Power Services, Inc. * @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc. * @license http://www.invisionpower.com/legal/standards/ * @package IPS Social Suite * @subpackage Nexus * @since 7 Apr 2014 * @version SVN_VERSION_NUMBER */ namespace IPS\nexus\Gateway\Stripe; /* To prevent PHP errors (extending class does not exist) revealing path */ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Stripe Pay Out Gateway */ class _Payout extends \IPS\nexus\Payout { /** * ACP Settings * * @return array */ public static function settings() { $settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE ); if ( !isset( $settings['Stripe'] ) or !count( $settings['Stripe'] ) ) { try { $method = \IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_gateway=? AND m_active=1', 'Stripe' ) )->first(); $_settings = json_decode( $method['m_settings'], TRUE ); $settings['Stripe']['secret_key'] = $_settings['secret_key']; } catch ( \UnderflowException $e ) { } } return array( new \IPS\Helpers\Form\Text( 'stripe_secret_key', ( isset( $settings['Stripe'] ) and isset( $settings['Stripe']['secret_key'] ) ) ? $settings['Stripe']['secret_key'] : NULL ) ); } /** * Payout Form * * @return array */ public static function form() { $return = array(); /* Get any details we've used before */ $previous = \IPS\Db::i()->select( 'po_data', 'nexus_payouts', array( 'po_member=? AND po_gateway=?', \IPS\Member::loggedIn()->member_id, 'Stripe' ) ); if ( count( $previous ) ) { $options = array(); foreach ( $previous as $id ) { $recipient = static::api( "recipients/{$id}", NULL, 'get' ); $options[ $id ] = "{$recipient['active_account']['bank_name']} - XXXX{$recipient['active_account']['last4']}"; } $options[0] = 'other'; $return[] = new \IPS\Helpers\Form\Radio( 'stripe_recipient', NULL, NULL, array( 'options' => $options, 'toggles' => array( 0 => array( 'stripe_country', 'stripe_routing_number', 'stripe_account_number', 'stripe_account_type' ) ) ) ); } /* Required Validation */ $requiredValidation = function( $val ) { if ( !$val and \IPS\Request::i()->withdraw_method === 'Stripe' and isset( \IPS\Request::i()->stripe_recipient ) and !\IPS\Request::i()->stripe_recipient ) { throw new \DomainException('form_required'); } }; /* Build form for new */ return array_merge( $return, array( 'country' => new \IPS\Helpers\Form\Select( 'stripe_country', 'US', NULL, array( 'options' => array_map( function( $val ) { return 'country-' . $val; }, array_combine( \IPS\GeoLocation::$countries, \IPS\GeoLocation::$countries ) ) ), NULL, NULL, NULL, 'stripe_country' ), 'routing_number' => new \IPS\Helpers\Form\Text( 'stripe_routing_number', NULL, NULL, array(), $requiredValidation, NULL, NULL, 'stripe_routing_number' ), 'account_number' => new \IPS\Helpers\Form\Text( 'stripe_account_number', NULL, NULL, array(), $requiredValidation, NULL, NULL, 'stripe_account_number' ), 'account_type' => new \IPS\Helpers\Form\Radio( 'stripe_account_type', 'individual', NULL, array( 'options' => array( 'individual' => 'stripe_account_type_individual', 'corporation' => 'stripe_account_type_corporation' ), 'toggles' => array( 'individual' => array( 'stripe_individual_name' ), 'corporation' => array( 'stripe_corporation_name' ) ) ), NULL, NULL, NULL, 'stripe_account_type' ), 'individual_name' => new \IPS\Helpers\Form\Text( 'stripe_individual_name', \IPS\nexus\Customer::loggedIn()->cm_name, NULL, array(), function( $val ) { if ( !$val and \IPS\Request::i()->withdraw_method === 'Stripe' and isset( \IPS\Request::i()->stripe_recipient ) and !\IPS\Request::i()->stripe_recipient and \IPS\Request::i()->stripe_account_type === 'individual' ) { throw new \DomainException('form_required'); } }, NULL, NULL, 'stripe_individual_name' ), 'corporation_name' => new \IPS\Helpers\Form\Text( 'stripe_corporation_name', NULL, NULL, array(), function( $val ) { if ( !$val and \IPS\Request::i()->withdraw_method === 'Stripe' and isset( \IPS\Request::i()->stripe_recipient ) and !\IPS\Request::i()->stripe_recipient and \IPS\Request::i()->stripe_account_type === 'corporation' ) { throw new \DomainException('form_required'); } }, NULL, NULL, 'stripe_corporation_name' ), ) ); } /** * Get data and validate * * @param array $values Values from form * @return mixed * @throws \DomainException */ public function getData( array $values ) { if ( isset( $values['stripe_recipient'] ) and $values['stripe_recipient'] ) { return $values['stripe_recipient']; } $recipient = static::api( 'recipients', array( 'name' => $values['stripe_account_type'] === 'individual' ? $values['stripe_individual_name'] : $values['stripe_corporation_name'], 'type' => $values['stripe_account_type'], 'bank_account' => array( 'country' => $values['stripe_country'], 'routing_number' => $values['stripe_routing_number'], 'account_number' => $values['stripe_account_number'] ), 'metadata' => array( 'id' => \IPS\Member::loggedIn()->member_id ), ) ); return $recipient['id']; } /** * Process * * @return void * @throws \Exception */ public function process() { $response = static::api( 'transfers', array( 'amount' => $this->amount->amount, 'currency' => $this->amount->currency, 'recipient' => $this->data ) ); $this->status = static::STATUS_COMPLETE; $this->completed = new \IPS\DateTime; $this->gw_id = $response['id']; $this->save(); } /** * Get recipient * * @return array */ public function recipient() { return static::api( "recipients/{$this->data}", NULL, 'get' ); } /** * Send API Request * * @param string $uri The API to request (e.g. "charges") * @param array $data The data to send * @param string $method Method (get/post) * @return array * @throws \IPS\Http|Exception * @throws \IPS\nexus\Gateway\PayPal\Exception */ protected static function api( $uri, $data=NULL, $method='post' ) { $settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE ); $response = \IPS\Http\Url::external( 'https://api.stripe.com/v1/' . $uri ) ->request() ->setHeaders( array( 'Stripe-Version' => '2014-01-31' ) ) ->login( $settings['Stripe']['secret_key'], '' ) ->$method( $data ) ->decodeJson(); if ( isset( $response['error'] ) ) { throw new \DomainException( $response['error']['message'] ); } return $response; } }