├── .gitignore ├── src ├── MoipAuthentication.php ├── Contracts │ ├── ResourceManager.php │ └── CookieManager.php ├── MoipFacade.php ├── Http │ ├── HTTPAuthenticator.php │ ├── AbstractHttp.php │ ├── AbstractHTTPRequest.php │ ├── HTTPRequest.php │ ├── Cookie.php │ ├── HTTPResponse.php │ ├── CURL.php │ ├── HTTPCookieManager.php │ └── HTTPConnection.php ├── MoipOAuth.php ├── MoipBasicAuth.php ├── MoipServiceProvider.php ├── Resource │ ├── BillingInfo.php │ ├── Payment.php │ ├── Event.php │ ├── Invoice.php │ ├── MoipResponse.php │ ├── Coupon.php │ ├── Subscriber.php │ ├── Plan.php │ ├── MoipResource.php │ └── Subscription.php ├── config │ └── moip.php ├── MoipError.php └── Moip.php ├── composer.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/storage 3 | /vendor 4 | /.idea 5 | Homestead.json 6 | Homestead.yaml 7 | .env 8 | composer.lock 9 | **/.DS_Store -------------------------------------------------------------------------------- /src/MoipAuthentication.php: -------------------------------------------------------------------------------- 1 | accessToken = $accessToken; 24 | } 25 | 26 | /** 27 | * Authentication of a HTTP request. 28 | * 29 | * @param \Zabaala\Moip\Http\HTTPRequest $httpRequest 30 | */ 31 | public function authenticate(HTTPRequest $httpRequest) 32 | { 33 | $httpRequest->addRequestHeader('Authorization', 'OAuth '.$this->accessToken); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/MoipBasicAuth.php: -------------------------------------------------------------------------------- 1 | token = $token; 32 | $this->key = $key; 33 | } 34 | 35 | /** 36 | * Authentication of a HTTP request. 37 | * 38 | * @param \Zabaala\Moip\Http\HTTPRequest $httpRequest 39 | */ 40 | public function authenticate(HTTPRequest $httpRequest) 41 | { 42 | $httpRequest->addRequestHeader('Authorization', 'Basic '.base64_encode($this->token.':'.$this->key)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Http/AbstractHttp.php: -------------------------------------------------------------------------------- 1 | requestHeader[$key])) { 24 | $this->requestHeader[$key] = array('name' => $name, 25 | 'value' => $value, 26 | ); 27 | 28 | return true; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | throw new InvalidArgumentException('Name and value MUST be scalar'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MoipServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes( 26 | [$configPath => config_path('moip.php')], 27 | 'moip' 28 | ); 29 | 30 | $this->mergeConfigFrom($configPath, 'moip'); 31 | } 32 | 33 | /** 34 | * Register the service provider. 35 | */ 36 | public function register() { 37 | 38 | $this->app->bind('moip', function($app){ 39 | 40 | $authentication = new MoipBasicAuth(\Config::get('moip.api.token'), \Config::get('moip.api.key')); 41 | 42 | return new Moip($authentication, \Config::get('moip.endpoint')); 43 | }); 44 | 45 | $this->app->alias('moip', 'Zabaala\Moip\Moip'); 46 | } 47 | 48 | /** 49 | * @return array 50 | */ 51 | public function provides() 52 | { 53 | return ['moip']; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Contracts/CookieManager.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 27 | } 28 | 29 | /** 30 | * Set subscriber code. 31 | * 32 | * @param $code 33 | */ 34 | public function setSubscriberCode($code) { 35 | $this->subscriber_code = $code; 36 | } 37 | 38 | /** 39 | * Create a new Subscriber. 40 | * 41 | * @return stdClass 42 | */ 43 | public function update() 44 | { 45 | return $this->updateResource(sprintf('/%s', str_replace('{{subscriber_code}}', $this->subscriber_code, self::PATH))); 46 | } 47 | 48 | 49 | /** 50 | * Set credit card of the Subscriber. 51 | * 52 | * @param int $number Card number. 53 | * @param int $expirationMonth Card expiration month. 54 | * @param int $expirationYear Year card expiration. 55 | * @param $holder_name 56 | * 57 | * @return $this 58 | */ 59 | public function setCreditCard( 60 | $number, 61 | $expirationMonth, 62 | $expirationYear, 63 | $holder_name 64 | ) 65 | { 66 | $this->data->credit_card = new stdClass(); 67 | $this->data->credit_card->number = $number; 68 | $this->data->credit_card->holder_name = $holder_name; 69 | $this->data->credit_card->expiration_month = $expirationMonth; 70 | $this->data->credit_card->expiration_year = $expirationYear; 71 | 72 | return $this; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Resource/Payment.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 71 | } 72 | 73 | /** 74 | * Set Subscription code. 75 | * 76 | * @param $code 77 | */ 78 | public function setInvoiceCode($code) { 79 | $this->invoice_code = $code; 80 | } 81 | 82 | /** 83 | * Find all Invoices. 84 | * 85 | * @return stdClass 86 | */ 87 | public function all() 88 | { 89 | return $this->getByPath(sprintf('/%s/?limit=20000', str_replace('{{invoice_code}}', $this->invoice_code, self::PATH_ALL)), true); 90 | } 91 | 92 | /** 93 | * Find a Invoice. 94 | * 95 | * @param string $id 96 | * 97 | * @return stdClass 98 | */ 99 | public function get($id) 100 | { 101 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $id)); 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/Resource/Event.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 17 | $this->data->type = null; 18 | $this->data->createdAt = null; 19 | $this->data->descriotion = null; 20 | } 21 | 22 | /** 23 | * Get event Type. 24 | * 25 | * @return string possible values: 26 | * ORDER.CREATED 27 | * ORDER.PAID 28 | * ORDER.NOT_PAID 29 | * ORDER.PAID 30 | * ORDER.REVERTED 31 | * PAYMENT.AUTHORIZED 32 | * PAYMENT.IN_ANALYSIS 33 | * PAYMENT.CANCELLED 34 | * ENTRY.SETTLED 35 | * PLAN.CREATED 36 | * PLAN.UPDATED 37 | * PLAN.ACTIVATED 38 | * PLAN.INACTIVATED 39 | * CUSTOMER.CREATED 40 | * CUSTOMER.UPDATED 41 | * SUBSCRIPTION.CREATED 42 | * SUBSCRIPTION.UPDATE 43 | * SUBSCRIPTION.ACTIVATED 44 | * SUBSCRIPTION.SUSPENDED 45 | * SUBSCRIPTION.CANCELED 46 | * INVOICE.CREATED 47 | * INVOICE.UPDATED 48 | */ 49 | public function getType() 50 | { 51 | return $this->data->type; 52 | } 53 | 54 | /** 55 | * Get creation date of the event. 56 | * 57 | * @return \DateTime 58 | */ 59 | public function getCreatedAt() 60 | { 61 | // todo: didn't find Events on documentation but i'm assuming it's a datetime, have to confirm it 62 | return $this->getIfSetDateTime('createdAt'); 63 | } 64 | 65 | /** 66 | * Get event Description. 67 | * 68 | * @return string 69 | */ 70 | public function getDescription() 71 | { 72 | return $this->data->description; 73 | } 74 | 75 | /** 76 | * Populate Event. 77 | * 78 | * @param \stdClass $response 79 | * 80 | * @return \stdClass 81 | */ 82 | protected function populate(stdClass $response) 83 | { 84 | $this->data = $response; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Resource/Invoice.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 36 | } 37 | 38 | /** 39 | * Set Subscription code. 40 | * 41 | * @param $code 42 | */ 43 | public function setSubscriptionCode($code) { 44 | $this->subscription_code = $code; 45 | } 46 | 47 | /** 48 | * Find all Invoices. 49 | * 50 | * @return stdClass 51 | */ 52 | public function all() 53 | { 54 | return $this->getByPath(sprintf('/%s/?limit=20000', str_replace('{{subscription_code}}', $this->subscription_code, self::PATH_ALL)), true); 55 | } 56 | 57 | /** 58 | * Find a Invoice. 59 | * 60 | * @param string $id 61 | * 62 | * @return stdClass 63 | */ 64 | public function get($id) 65 | { 66 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $id)); 67 | } 68 | 69 | /** 70 | * Retry a payment. 71 | * 72 | * @param $id 73 | * @return stdClass 74 | */ 75 | public function retry($id) 76 | { 77 | return $this->createResource(sprintf('/%s/%s/retry', self::PATH, $id)); 78 | } 79 | 80 | /** 81 | * Update boleto due date. 82 | * 83 | * @param $invoice_id 84 | * @param $day 85 | * @param $month 86 | * @param $year 87 | */ 88 | public function updateDueDateBoleto($invoice_id, $day, $month, $year) 89 | { 90 | $obj = new stdClass(); 91 | $obj->day = $day; 92 | $obj->month = $month; 93 | $obj->year = $year; 94 | 95 | $this->data = $obj; 96 | 97 | return $this->createResource(sprintf('/%s/%s/boletos', self::PATH, $invoice_id)); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/Http/AbstractHTTPRequest.php: -------------------------------------------------------------------------------- 1 | close(); 42 | } 43 | 44 | /** 45 | * Adiciona um campo de cabeçalho para ser enviado com a requisição. 46 | * 47 | * @param string $name Nome do campo de cabeçalho. 48 | * @param string $value Valor do campo de cabeçalho. 49 | * @param bool $override Indica se o campo deverá ser sobrescrito caso já tenha sido definido. 50 | * 51 | * @return bool 52 | * 53 | * @throws \InvalidArgumentException Se o nome ou o valor do campo não forem valores scalar. 54 | * 55 | * @see \Zabaala\Moip\Http\HTTPRequest::addRequestHeader() 56 | */ 57 | public function addRequestHeader($name, $value, $override = true) 58 | { 59 | return $this->addHeaderRequest($name, $value, $override); 60 | } 61 | 62 | /** 63 | * Autentica uma requisição HTTP. 64 | * 65 | * @param \Zabaala\Moip\Http\HTTPAuthenticator $authenticator 66 | * 67 | * @see \Zabaala\Moip\Http\HTTPRequest::authenticate() 68 | */ 69 | public function authenticate(HTTPAuthenticator $authenticator) 70 | { 71 | $authenticator->authenticate($this); 72 | } 73 | 74 | /** 75 | * Abre a requisição. 76 | * 77 | * 78 | * @see \Zabaala\Moip\Http\HTTPRequest::getResponse() 79 | */ 80 | public function getResponse() 81 | { 82 | return $this->httpResponse; 83 | } 84 | 85 | /** 86 | * Define um parâmetro que será enviado com a requisição, um parâmetro é um 87 | * par nome-valor que será enviado como uma query string. 88 | * 89 | * @param string $name Nome do parâmetro. 90 | * @param string $value Valor do parâmetro. 91 | * 92 | * @throws \InvalidArgumentException Se o nome ou o valor do campo não forem valores scalar. 93 | * 94 | * @see \Zabaala\Moip\Http\HTTPRequest::setParameter() 95 | */ 96 | public function setParameter($name, $value) 97 | { 98 | $this->requestParameter[$name] = $value; 99 | } 100 | 101 | /** 102 | * @see \Moip\Http\HTTPRequest::setRequestBody() 103 | * 104 | * @param string $requestBody 105 | */ 106 | public function setRequestBody($requestBody) 107 | { 108 | $this->requestBody = $requestBody; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/config/moip.php: -------------------------------------------------------------------------------- 1 | env('MOIP_CLIENT', 'L5 Moip Assinaturas - Package'), 13 | 14 | /* 15 | |-------------------------------------------------------------------------- 16 | | API Token 17 | |-------------------------------------------------------------------------- 18 | | 19 | | As novas APIs de pagamento do Moip permitem que você receba pagamentos 20 | | em seu website ou em sua aplicação móvel de forma simples e segura. 21 | | Para isso, você precisa possuir uma conta criada no Moip, além de 22 | | possuir um Moip API Token e um Moip API KEY, para autenticar-se no 23 | | sistema do Moip. 24 | | 25 | */ 26 | 'api' => [ 27 | 'token' => env('MOIP_API_TOKEN'), 28 | 'key' => env('MOIP_API_KEY') 29 | ], 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Authorization Code 34 | |-------------------------------------------------------------------------- 35 | | 36 | | O Moip Assinaturas utiliza webhooks para notificar os eventos 37 | | provenientes da sua conta em tempo real. 38 | | 39 | | Para garantir que as notificações têm como origem o Moip Assinatura, 40 | | nós precisaremos verificar o authorization_code, que é um parâmetro que 41 | | vem no HEADER das requisições do Moip. Essa é uma informação de alta 42 | | importância, para garantir a segurança da sua aplicação. 43 | | 44 | */ 45 | 'authorization' => [ 46 | 'check' => env('MOIP_AUTHORIZATION_CHECK', true), 47 | 'code' => env('MOIP_AUTHORIZATION_CODE', true), 48 | ], 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | Endpoint 53 | |-------------------------------------------------------------------------- 54 | | 55 | | O Moip fornece dois endpoints, para que sua aplicação se integre 56 | | com o Moip. Você pode utilizar o ambiente de produção para submeter 57 | | dados e executar operações reais ou pode utilizar o sandbox, para 58 | | simular suas atividades de cobrança. 59 | | 60 | | Supported: "sandbox", "production" 61 | | Default: "sandbox" 62 | | 63 | */ 64 | 'endpoint' => env('MOIP_ENDPOINT', 'sandbox'), 65 | 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Endpoint URL 69 | |-------------------------------------------------------------------------- 70 | | 71 | | Você pode optar por sobrescrever o endereço padrão do ENDPOINT do Moip, 72 | | para utilizar um endereço alternativo. 73 | | 74 | | ATENÇÃO: 75 | | É altamente recomendado que essa alteração seja feita se o ambiente 76 | | do Moip possuir uma nova URL válida. 77 | | 78 | | Defaults: 79 | | production: api.moip.com.br 80 | | sandbox: sandbox.moip.com.br 81 | | 82 | */ 83 | 'url' => [ 84 | 'sandbox' => 'sandbox.moip.com.br', 85 | 'production' => 'api.moip.com.br', 86 | ], 87 | ]; -------------------------------------------------------------------------------- /src/Resource/MoipResponse.php: -------------------------------------------------------------------------------- 1 | resource = $resource; 40 | $this->httpResponse = $httpResponse; 41 | 42 | $this->error = new MoipError(); 43 | } 44 | 45 | /** 46 | * Make 200 response. 47 | * 48 | * @return boolean 49 | */ 50 | protected function code200() { 51 | return true; 52 | } 53 | 54 | /** 55 | * Make 201 response. 56 | * 57 | * @return boolean 58 | */ 59 | protected function code201(){ 60 | return true; 61 | } 62 | 63 | /** 64 | * Make 400 response. 65 | * 66 | * @return MoipError 67 | */ 68 | protected function code400() { 69 | $this->error->pushMultiple($this->httpResponse->getContent()); 70 | return $this->error; 71 | } 72 | 73 | /** 74 | * Make 401 response. 75 | * 76 | * @return MoipError 77 | */ 78 | protected function code401() { 79 | $error = json_decode($this->httpResponse->getContent()); 80 | $this->error->push('401', $error->ERROR); 81 | 82 | return $this->error; 83 | 84 | } 85 | 86 | /** 87 | * Make 404 response. 88 | * 89 | * @return MoipError 90 | */ 91 | protected function code404() { 92 | $this->error->push('404', 'Moip says: Path not found on this server. Please your request and try again.'); 93 | return $this->error; 94 | } 95 | 96 | /** 97 | * Make 405 response code implementation. 98 | * 99 | * @return MoipError 100 | */ 101 | protected function code405() { 102 | $this->error->push('405', 'Moip says: Method/Verb not allowed.'); 103 | return $this->error; 104 | } 105 | 106 | /** 107 | * Trait Moip Response by code. 108 | * 109 | * @param $code 110 | */ 111 | public function byCode($code) { 112 | $functionName = 'code' . $code; 113 | return $this->$functionName(); 114 | } 115 | 116 | public function getResponse() { 117 | return $this->httpResponse; 118 | } 119 | 120 | /** 121 | * @return MoipError 122 | */ 123 | public function getError() { 124 | return $this->error; 125 | } 126 | 127 | /** 128 | * Create a custom not found function exception. 129 | * 130 | * @param $name 131 | * @param $args 132 | */ 133 | public function __call($name, $args) { 134 | throw new \BadFunctionCallException(sprintf("Function %s not found on the current context.", $name)); 135 | } 136 | 137 | } -------------------------------------------------------------------------------- /src/MoipError.php: -------------------------------------------------------------------------------- 1 | hasError = true; 32 | 33 | $err = new stdClass(); 34 | $err->code = $code; 35 | $err->description = $description; 36 | 37 | $this->errors[] = $err; 38 | 39 | } 40 | 41 | /** 42 | * Push multiples MoipErrors. 43 | * 44 | * @param $errors 45 | */ 46 | public function pushMultiple($errors) 47 | { 48 | \Log::info($errors); 49 | 50 | $errors = json_decode($errors); 51 | $errors = $errors->errors; 52 | 53 | if( !count($errors) ){ 54 | return ; 55 | } 56 | 57 | $this->hasError = true; 58 | $this->errors = $errors; 59 | 60 | } 61 | 62 | /** 63 | * Check if has error. 64 | * 65 | * @return bool 66 | */ 67 | public function has() { 68 | return $this->hasError; 69 | } 70 | 71 | /** 72 | * Get last error description 73 | * 74 | * @param bool $withCode 75 | * @return string 76 | */ 77 | public function last($withCode = false) { 78 | return $this->getByPosition('last', $withCode); 79 | } 80 | 81 | /** 82 | * Get first error description 83 | * 84 | * @param bool $withCode 85 | * @return string 86 | */ 87 | public function first($withCode = false) { 88 | return $this->getByPosition('first', $withCode); 89 | } 90 | 91 | /** 92 | * Get all errors. 93 | * 94 | * @return mixed 95 | */ 96 | public function all() { 97 | return $this->errors; 98 | } 99 | 100 | /** 101 | * Get error description by position. 102 | * 103 | * @param string $position 104 | * @param bool $withCode 105 | * @return string 106 | */ 107 | protected function getByPosition($position = 'first', $withCode = false) { 108 | 109 | if($this->has()) { 110 | switch($position) { 111 | case 'first': 112 | $error = $this->errors[0]; 113 | break; 114 | 115 | case 'last': 116 | case 'end': 117 | $error = end($this->errors); 118 | break; 119 | 120 | default: 121 | $error = $this->errors[0]; 122 | break; 123 | } 124 | 125 | if(! @$error->description) { 126 | return $error->code; 127 | } 128 | 129 | return ($withCode ? $error->code . ' - ' : '') . @$error->description; 130 | } 131 | 132 | return ''; 133 | 134 | } 135 | 136 | /** 137 | * Becomes MoipError to string getting the first error. 138 | * 139 | * @return string 140 | */ 141 | public function __toString() { 142 | return $this->first(); 143 | } 144 | 145 | } -------------------------------------------------------------------------------- /src/Http/HTTPRequest.php: -------------------------------------------------------------------------------- 1 | moipAuthentication = $moipAuthentication; 61 | 62 | $this->endpoint = \Config::get('moip.url.' . $endpoint); 63 | } 64 | 65 | /** 66 | * Create a new api connection instance. 67 | * 68 | * @param HTTPConnection $http_connection 69 | * 70 | * @return HTTPConnection 71 | */ 72 | public function createConnection(HTTPConnection $http_connection) 73 | { 74 | $http_connection->initialize($this->endpoint, true); 75 | $http_connection->addHeader('Accept', 'application/json'); 76 | $http_connection->setAuthenticator($this->moipAuthentication); 77 | 78 | return $http_connection; 79 | } 80 | 81 | /** 82 | * Create new Plans instance. 83 | * 84 | * @return Plan 85 | */ 86 | public function plans() { 87 | return new Plan($this); 88 | } 89 | 90 | /** 91 | * Create new Billing Info instance. 92 | * 93 | * @return BillingInfo 94 | */ 95 | public function billingInfos() { 96 | return new BillingInfo($this); 97 | } 98 | 99 | /** 100 | * Create new Subscriber instance. 101 | * 102 | * @return Subscriber 103 | */ 104 | public function subscribers() { 105 | return new Subscriber($this); 106 | } 107 | 108 | /** 109 | * Create a new Subscription instance. 110 | * 111 | * @return Subscription 112 | */ 113 | public function subscriptions() { 114 | return new Subscription($this); 115 | } 116 | 117 | /** 118 | * Create a new Invoice instance. 119 | * 120 | * @return Invoice 121 | */ 122 | public function invoices() { 123 | return new Invoice($this); 124 | } 125 | 126 | /** 127 | * Create a new Payment instance. 128 | * 129 | * @return Payment 130 | */ 131 | public function payments() 132 | { 133 | return new Payment($this); 134 | } 135 | 136 | /** 137 | * Create a new Coupon instance. 138 | * 139 | * @return Coupon 140 | */ 141 | public function coupons() 142 | { 143 | return new Coupon($this); 144 | } 145 | 146 | /** 147 | * Get the endpoint. 148 | * 149 | * @return string 150 | */ 151 | public function getEndpoint() 152 | { 153 | return $this->endpoint; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/Http/Cookie.php: -------------------------------------------------------------------------------- 1 | name = (string) $name; 79 | $this->value = (string) $value; 80 | $this->domain = (string) $domain; 81 | 82 | if (is_numeric($expires)) { 83 | $this->expires = (int) $expires; 84 | } else { 85 | throw new InvalidArgumentException('Invalid expiration'); 86 | } 87 | 88 | $this->path = (string) $path; 89 | $this->secure = $secure === true; 90 | $this->comment = $comment; 91 | } 92 | 93 | /** 94 | * Retorna a representação do Cookie como uma string. 95 | * 96 | * @return string 97 | */ 98 | public function __toString() 99 | { 100 | return sprintf('%s=%s', $this->name, $this->value); 101 | } 102 | 103 | /** 104 | * Recupera o comentário do cookie. 105 | * 106 | * @return string 107 | */ 108 | public function getComment() 109 | { 110 | return $this->comment; 111 | } 112 | 113 | /** 114 | * Recupera o domínio do cookie. 115 | * 116 | * @return string 117 | */ 118 | public function getDomain() 119 | { 120 | return $this->domain; 121 | } 122 | 123 | /** 124 | * Recupera o timestamp da expiração do cookie. 125 | * 126 | * @return int 127 | */ 128 | public function getExpires() 129 | { 130 | return $this->expires; 131 | } 132 | 133 | /** 134 | * Recupera o nome do cookie. 135 | * 136 | * @return string 137 | */ 138 | public function getName() 139 | { 140 | return $this->name; 141 | } 142 | 143 | /** 144 | * Recupera o caminho do cookie. 145 | * 146 | * @return string 147 | */ 148 | public function getPath() 149 | { 150 | return $this->path; 151 | } 152 | 153 | /** 154 | * Recupera o valor do cookie. 155 | * 156 | * @return string 157 | */ 158 | public function getValue() 159 | { 160 | return $this->value; 161 | } 162 | 163 | /** 164 | * Verifica ambiente seguro. 165 | * Verifica se o User-Agent deve utilizar o 166 | * cookie apenas em ambiente seguro. 167 | * 168 | * @return bool 169 | */ 170 | public function isSecure() 171 | { 172 | return $this->secure; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/Resource/Coupon.php: -------------------------------------------------------------------------------- 1 | data = new \stdClass(); 20 | } 21 | 22 | /** 23 | * Find a Coupon. 24 | * 25 | * @param string $id 26 | * 27 | * @return stdClass 28 | */ 29 | public function find($id) 30 | { 31 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $id)); 32 | } 33 | 34 | /** 35 | * Get All Coupons. 36 | * 37 | * @return stdClass 38 | */ 39 | public function all() 40 | { 41 | return parent::getAllByPath(sprintf('/%s/', self::PATH)); 42 | } 43 | 44 | /** 45 | * Create a new Coupon. 46 | * 47 | * @return stdClass 48 | */ 49 | public function create() 50 | { 51 | return $this->createResource(sprintf('/%s', self::PATH)); 52 | } 53 | 54 | /** 55 | * Update a Coupon. 56 | * 57 | * @return stdClass 58 | */ 59 | public function update() { 60 | return $this->updateResource(sprintf('/%s/%s', self::PATH, $this->data->code)); 61 | } 62 | 63 | /** 64 | * Set code of coupon. 65 | * 66 | * @param $value 67 | */ 68 | public function setCode($value) 69 | { 70 | $this->data->code = $value; 71 | } 72 | 73 | /** 74 | * Set name of coupon. 75 | * 76 | * @param $value 77 | */ 78 | public function setName($value) 79 | { 80 | $this->data->name = $value; 81 | } 82 | 83 | /** 84 | * Set description of coupon. 85 | * 86 | * @param $value 87 | */ 88 | public function setDescription($value) 89 | { 90 | $this->data->description = $value; 91 | } 92 | 93 | /** 94 | * Set discount of coupon. 95 | * 96 | * @param $value 97 | * @param $type 98 | */ 99 | public function setDiscount($value, $type) 100 | { 101 | $this->data->discount = new \stdClass(); 102 | $this->data->discount->value = $value; 103 | $this->data->discount->type = $type; 104 | } 105 | 106 | /** 107 | * Set status of coupon. 108 | * 109 | * @param $value 110 | */ 111 | public function setStatus($value) 112 | { 113 | $this->data->status = $value; 114 | } 115 | 116 | /** 117 | * Set duration of coupon. 118 | * 119 | * @param $type 120 | * @param $occurrences 121 | */ 122 | public function setDuration($type, $occurrences = '') 123 | { 124 | $this->data->duration = new \stdClass(); 125 | $this->data->duration->type = $type; 126 | $this->data->duration->occurrences = $occurrences; 127 | } 128 | 129 | /** 130 | * Set max redemptions. 131 | * 132 | * @param $value 133 | */ 134 | public function setMaxRedemptions($value) 135 | { 136 | $this->data->max_redemptions = $value; 137 | } 138 | 139 | /** 140 | * Set Expiration date of coupon. 141 | * @param $day 142 | * @param $month 143 | * @param $year 144 | */ 145 | public function setExpirationDate($day, $month, $year) 146 | { 147 | $this->data->expiration_date = new \stdClass(); 148 | $this->data->expiration_date->day = $day; 149 | $this->data->expiration_date->month = $month; 150 | $this->data->expiration_date->year = $year; 151 | } 152 | 153 | /** 154 | * Activate a coupon. 155 | * 156 | * @return stdClass 157 | */ 158 | public function activate() 159 | { 160 | return $this->toggleStatus('active'); 161 | } 162 | 163 | /** 164 | * @return stdClass 165 | */ 166 | public function inactivate() 167 | { 168 | return $this->toggleStatus('inactive'); 169 | } 170 | 171 | /** 172 | * Toggle coupon status. 173 | * @see http://dev.moip.com.br/assinaturas-api/?php#ativar-e-inativar-coupons-put 174 | * 175 | * @param string $action Possible values: activate | inactivate. 176 | * @return stdClass 177 | */ 178 | protected function toggleStatus($action) 179 | { 180 | return $this->updateResource(sprintf('/%s/%s/%s', self::PATH, $this->data->code, $action)); 181 | } 182 | 183 | } -------------------------------------------------------------------------------- /src/Resource/Subscriber.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 27 | } 28 | 29 | /** 30 | * Create a new Subscriber. 31 | * 32 | * @return stdClass 33 | */ 34 | public function create() 35 | { 36 | return $this->createResource(sprintf('/%s', self::PATH)); 37 | } 38 | 39 | /** 40 | * Update a Subscriber. 41 | * 42 | * @return stdClass 43 | */ 44 | public function update() { 45 | return $this->updateResource(sprintf('/%s/%s', self::PATH, $this->data->code)); 46 | } 47 | 48 | /** 49 | * Find a Subscriber. 50 | * 51 | * @param string $id 52 | * 53 | * @return stdClass 54 | */ 55 | public function get($id) 56 | { 57 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $id)); 58 | } 59 | 60 | /** 61 | * Get all Subscribers. 62 | * 63 | * @return stdClass 64 | */ 65 | public function all() 66 | { 67 | return $this->getByPath(sprintf('/%s/?limit=20000', self::PATH), true); 68 | } 69 | 70 | /** 71 | * Set Code of the Subscriber. 72 | * 73 | * @param $code 74 | * 75 | * @return $this 76 | */ 77 | public function setCode($code) 78 | { 79 | $this->data->code = $code; 80 | 81 | return $this; 82 | } 83 | 84 | /** 85 | * Set e-mail of the Subscriber. 86 | * 87 | * @param string $email Email Subscriber. 88 | * 89 | * @return $this 90 | */ 91 | public function setEmail($email) 92 | { 93 | $this->data->email = $email; 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * Set fullname of the Subscriber. 100 | * 101 | * @param string $fullname Customer's full name. 102 | * 103 | * @return $this 104 | */ 105 | public function setFullName($fullname) 106 | { 107 | $this->data->fullname = $fullname; 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * Set fullname of the Subscriber. 114 | * 115 | * @param $cpf 116 | * 117 | * @return $this 118 | */ 119 | public function setCpf($cpf) 120 | { 121 | $this->data->cpf = $cpf; 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * Set phone of the Subscriber. 128 | * 129 | * @param int $areaCode DDD telephone. 130 | * @param int $number Telephone number. 131 | * 132 | * @return $this 133 | */ 134 | public function setPhone($areaCode, $number) 135 | { 136 | $this->data->phone_area_code = $areaCode; 137 | $this->data->phone_number = $number; 138 | 139 | return $this; 140 | } 141 | 142 | /** 143 | * Set birth date of the Subscriber. 144 | * 145 | * @param $day 146 | * @param $month 147 | * @param $year 148 | * 149 | * @return $this 150 | */ 151 | public function setBirthDate($day, $month, $year) 152 | { 153 | $this->data->birthdate_day = $day; 154 | $this->data->birthdate_month = $month; 155 | $this->data->birthdate_year = $year; 156 | 157 | return $this; 158 | } 159 | 160 | /** 161 | * Add a new address to the Subscriber. 162 | * 163 | * @param string $street 164 | * @param string $number 165 | * @param string $district 166 | * @param string $city 167 | * @param string $state 168 | * @param string $zip 169 | * @param string $complement 170 | * @param string $country 171 | * 172 | * @return $this 173 | */ 174 | public function setAddress( 175 | $street, 176 | $number, 177 | $complement = null, 178 | $district, 179 | $city, 180 | $state, 181 | $zip, 182 | $country = self::ADDRESS_COUNTRY 183 | ) 184 | { 185 | $address = new stdClass(); 186 | $address->street = $street; 187 | $address->number = $number; 188 | $address->complement = $complement; 189 | $address->district = $district; 190 | $address->city = $city; 191 | $address->state = $state; 192 | $address->country = $country; 193 | $address->zipcode = $zip; 194 | 195 | $this->data->address = $address; 196 | 197 | return $this; 198 | } 199 | 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/Resource/Plan.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 20 | } 21 | 22 | /** 23 | * Set the Plan code. 24 | * 25 | * @param null $code 26 | */ 27 | public function setCode($code) { 28 | 29 | if ($code === null) { 30 | $this->data->code = uniqid(); 31 | } 32 | 33 | $this->data->code = $code; 34 | } 35 | 36 | /** 37 | * Set the plan name. Optional. 38 | * 39 | * @param $name 40 | */ 41 | public function setName($name) { 42 | $this->data->name = $name; 43 | } 44 | 45 | /** 46 | * Set the plan description. 47 | * 48 | * @param null $description 49 | */ 50 | public function setDescription($description) { 51 | $this->data->description = $description; 52 | } 53 | 54 | /** 55 | * Set amount of the plan. 56 | * 57 | * @param $amount 58 | */ 59 | public function setAmount($amount) { 60 | $this->data->amount = $amount; 61 | } 62 | 63 | /** 64 | * Set the plan setup fee. 65 | * 66 | * @param $setup_fee 67 | */ 68 | public function setSetupFee($setup_fee) { 69 | $this->data->setup_fee = $setup_fee; 70 | } 71 | 72 | /** 73 | * Sets the recurrence of the plan charging. 74 | * 75 | * @param string $unit. Unit can be: DAY, MONTH or YEAR. 76 | * @param int $length 77 | */ 78 | public function setInterval($unit = 'MONTH', $length = 1) { 79 | $this->data->interval = new stdClass(); 80 | $this->data->interval->unit = $unit; 81 | $this->data->interval->length = $length; 82 | } 83 | 84 | /** 85 | * Defines how many times the plan must happen. 86 | * 87 | * @param $billingCycles 88 | */ 89 | public function setBillingCycles($billingCycles) { 90 | $this->data->billing_cycles = $billingCycles; 91 | } 92 | 93 | /** 94 | * Set max quantity of the subscribes on the plan. 95 | * If no value was passed, there is no limit. 96 | * 97 | * @param null $maxQuantity 98 | */ 99 | public function setMaxQuantity($maxQuantity) { 100 | $this->data->max_qty = $maxQuantity; 101 | } 102 | 103 | public function setTrial($days = 0, $enabled = false, $hold_setup_fee = true) { 104 | $this->data->trial = new stdClass(); 105 | $this->data->trial->days = $days; 106 | $this->data->trial->enabled = $enabled; 107 | $this->data->trial->hold_setup_fee = $hold_setup_fee; 108 | } 109 | 110 | /** 111 | * Payment methods accepted by plan. 112 | * Default value: CREDIT_CARD. 113 | * 114 | * @param string $method 115 | */ 116 | public function setPaymentMethod($method = Payment::METHOD_CREDIT_CARD) { 117 | $this->data->payment_method = $method; 118 | } 119 | 120 | /** 121 | * Create a new Plan. 122 | * 123 | * @return stdClass 124 | */ 125 | public function create() 126 | { 127 | return $this->createResource(sprintf('/%s', self::PATH)); 128 | } 129 | 130 | /** 131 | * Update a Plan. 132 | * 133 | * @return stdClass 134 | */ 135 | public function update() { 136 | return $this->updateResource(sprintf('/%s/%s', self::PATH, $this->data->code)); 137 | } 138 | 139 | /** 140 | * Inactivate a Plan. 141 | * 142 | * @return stdClass 143 | */ 144 | public function inactivate() { 145 | return $this->toggleStatus('inactivate'); 146 | } 147 | 148 | /** 149 | * Activate a Plan. 150 | * 151 | * @return stdClass 152 | */ 153 | public function activate() { 154 | return $this->toggleStatus('activate'); 155 | } 156 | 157 | /** 158 | * Set Plan status. 159 | * 160 | * @param $status 161 | */ 162 | public function setStatus($status) { 163 | $this->data->status = $status; 164 | } 165 | 166 | /** 167 | * Activate / Deactivate a Plan. 168 | * @see http://dev.moip.com.br/assinaturas-api/?php#ativar-plano-put 169 | * 170 | * @param $action string Possible values: activate | inactivate. 171 | * @return stdClass 172 | */ 173 | protected function toggleStatus($action) 174 | { 175 | return $this->updateResource(sprintf('/%s/%s/%s', self::PATH, $this->data->code, $action)); 176 | } 177 | 178 | 179 | /** 180 | * Find a Plan. 181 | * 182 | * @param string $id 183 | * 184 | * @return stdClass 185 | */ 186 | public function find($id) 187 | { 188 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $id)); 189 | } 190 | 191 | /** 192 | * Get All Plans. 193 | * 194 | * @return stdClass 195 | */ 196 | public function all() 197 | { 198 | return parent::getAllByPath(sprintf('/%s/', self::PATH)); 199 | } 200 | 201 | } -------------------------------------------------------------------------------- /src/Http/HTTPResponse.php: -------------------------------------------------------------------------------- 1 | responseBody; 38 | } 39 | 40 | /** 41 | * Recupera o tamanho do corpo da resposta. 42 | * 43 | * @return int 44 | */ 45 | public function getContentLength() 46 | { 47 | return $this->getHeaderInt('Content-Length'); 48 | } 49 | 50 | /** 51 | * Recupera o tipo de conteúdo da resposta. 52 | * 53 | * @return string 54 | */ 55 | public function getContentType() 56 | { 57 | return $this->getHeader('Content-Type'); 58 | } 59 | 60 | /** 61 | * Recupera o código de status da resposta do servidor. 62 | * 63 | * @return int 64 | */ 65 | public function getStatusCode() 66 | { 67 | return $this->statusCode; 68 | } 69 | 70 | /** 71 | * Recupera a mensagem de status da resposta do servidor. 72 | * 73 | * @return string 74 | */ 75 | public function getStatusMessage() 76 | { 77 | return $this->statusMessage; 78 | } 79 | 80 | /** 81 | * Verifica se existe um cabeçalho de resposta HTTP. 82 | * 83 | * @param string $name Nome do cabeçalho 84 | * 85 | * @return bool 86 | */ 87 | public function hasResponseHeader($name) 88 | { 89 | return isset($this->responseHeader[strtolower($name)]); 90 | } 91 | 92 | /** 93 | * Recupera o valor um campo de cabeçalho da resposta HTTP. 94 | * 95 | * @param string $name Nome do campo de cabeçalho. 96 | * 97 | * @return string O valor do campo ou NULL se não estiver existir. 98 | */ 99 | public function getHeader($name) 100 | { 101 | $key = strtolower($name); 102 | 103 | if (isset($this->responseHeader[$key])) { 104 | if (!isset($this->responseHeader[$key]['name']) && 105 | is_array($this->responseHeader[$key])) { 106 | $values = array(); 107 | 108 | foreach ($this->responseHeader[$key] as $header) { 109 | $values[] = $header['value']; 110 | } 111 | 112 | return $values; 113 | } else { 114 | return $this->responseHeader[$key]['value']; 115 | } 116 | } 117 | 118 | return; 119 | } 120 | 121 | /** 122 | * Recupera um valor como inteiro de um campo de cabeçalho da resposta HTTP. 123 | * 124 | * @param string $name Nome do campo de cabeçalho. 125 | * 126 | * @return int 127 | */ 128 | public function getHeaderInt($name) 129 | { 130 | return (int) $this->getHeader($name); 131 | } 132 | 133 | /** 134 | * Recupera um valor como unix timestamp de um campo de cabeçalho da resposta HTTP. 135 | * 136 | * @param string $name Nome do campo de cabeçalho. 137 | * 138 | * @return int UNIX Timestamp ou NULL se não estiver definido. 139 | */ 140 | public function getHeaderDate($name) 141 | { 142 | $date = $this->getHeader($name); 143 | 144 | if (!is_null($date) && !empty($date)) { 145 | return strtotime($date); 146 | } 147 | } 148 | 149 | /** 150 | * Define a resposta da requisição HTTP. 151 | * 152 | * @param string $response Toda a resposta da requisição 153 | * @param \Zabaala\Moip\Http\CookieManager 154 | */ 155 | public function setRawResponse($response) 156 | { 157 | $parts = explode("\r\n\r\n", $response); 158 | 159 | if (count($parts) == 2) { 160 | $matches = array(); 161 | $this->responseBody = $parts[1]; 162 | 163 | if (preg_match_all( 164 | '/(HTTP\/[1-9]\.[0-9]\s+(?\d+)\s+(?.*)'. 165 | "|(?[^:]+)\\s*:\\s*(?.*))\r\n/m", 166 | $parts[0], $matches)) { 167 | foreach ($matches['statusCode'] as $offset => $match) { 168 | if (!empty($match)) { 169 | $this->statusCode = (int) $match; 170 | $this->statusMessage = $matches['statusMessage'][$offset]; 171 | break; 172 | } 173 | } 174 | 175 | foreach ($matches['headerName'] as $offset => $name) { 176 | if (!empty($name)) { 177 | $key = strtolower($name); 178 | $header = array('name' => $name, 179 | 'value' => $matches['headerValue'][$offset], 180 | ); 181 | 182 | if (isset($this->responseHeader[$key])) { 183 | if (isset($this->responseHeader[$key]['name'])) { 184 | $this->responseHeader[$key] = array( 185 | $this->responseHeader[$key], 186 | ); 187 | } 188 | 189 | $this->responseHeader[$key][] = $header; 190 | } else { 191 | $this->responseHeader[$key] = $header; 192 | } 193 | } 194 | } 195 | } 196 | } else { 197 | $this->responseBody = $response; 198 | } 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/Http/CURL.php: -------------------------------------------------------------------------------- 1 | openned) { 33 | curl_close($this->curlResource); 34 | $this->openned = false; 35 | } 36 | } 37 | 38 | /** 39 | * Executa a requisição HTTP em um caminho utilizando um método específico. 40 | * 41 | * @param string $method Método da requisição. 42 | * @param string $path Alvo da requisição. 43 | * 44 | * @return bool Resposta HTTP. 45 | * 46 | * @throws \BadMethodCallException Se não houver uma conexão inicializada. 47 | * 48 | * @see \Zabaala\Moip\Http\HTTPRequest::execute() 49 | */ 50 | public function execute($path = '/', $method = HTTPRequest::GET) 51 | { 52 | $targetURL = $this->httpConnection->getURI().$path; 53 | $hasParameters = count($this->requestParameter) > 0; 54 | $query = $hasParameters ? http_build_query($this->requestParameter) : null; 55 | 56 | switch ($method) { 57 | case HTTPRequest::PUT : 58 | case HTTPRequest::POST : 59 | if ($method != HTTPRequest::POST) { 60 | curl_setopt($this->curlResource, CURLOPT_CUSTOMREQUEST, 61 | $method); 62 | } else { 63 | curl_setopt($this->curlResource, CURLOPT_POST, 1); 64 | } 65 | 66 | if (empty($this->requestBody)) { 67 | curl_setopt($this->curlResource, CURLOPT_POSTFIELDS, $query); 68 | } else { 69 | if ($hasParameters) { 70 | $targetURL .= '?'.$query; 71 | } 72 | 73 | curl_setopt($this->curlResource, CURLOPT_POSTFIELDS, 74 | $this->requestBody); 75 | } 76 | 77 | curl_setopt($this->curlResource, CURLOPT_URL, $targetURL); 78 | 79 | break; 80 | case HTTPRequest::DELETE : 81 | case HTTPRequest::HEAD : 82 | case HTTPRequest::OPTIONS : 83 | case HTTPRequest::TRACE : 84 | curl_setopt($this->curlResource, CURLOPT_CUSTOMREQUEST, $method); 85 | case HTTPRequest::GET : 86 | if ($hasParameters) { 87 | $targetURL .= '?'.$query; 88 | } 89 | 90 | curl_setopt($this->curlResource, CURLOPT_URL, $targetURL); 91 | 92 | break; 93 | default : 94 | throw new UnexpectedValueException('Unknown method.'); 95 | } 96 | 97 | $resp = curl_exec($this->curlResource); 98 | $errno = curl_errno($this->curlResource); 99 | $error = curl_error($this->curlResource); 100 | 101 | if ($errno != 0) { 102 | throw new RuntimeException($error, $errno); 103 | } 104 | 105 | $this->httpResponse = new HTTPResponse(); 106 | $this->httpResponse->setRawResponse($resp); 107 | 108 | if ($this->httpResponse->hasResponseHeader('Set-Cookie')) { 109 | $cookieManager = $this->httpConnection->getCookieManager(); 110 | 111 | if ($cookieManager != null) { 112 | $cookieManager->setCookie( 113 | $this->httpResponse->getHeader('Set-Cookie'), 114 | $this->httpConnection->getHostName()); 115 | } 116 | } 117 | 118 | $statusCode = $this->httpResponse->getStatusCode(); 119 | 120 | return $statusCode < 400; 121 | } 122 | 123 | /** 124 | * Abre a requisição. 125 | * 126 | * @param \Zabaala\Moip\Http\HTTPConnection $httpConnection Conexão HTTP relacionada com essa requisição 127 | * 128 | * @see \Zabaala\Moip\Http\HTTPRequest::open() 129 | */ 130 | public function open(HTTPConnection $httpConnection) 131 | { 132 | if (function_exists('curl_init')) { 133 | $this->close(); 134 | 135 | $curl = curl_init(); 136 | 137 | if (is_resource($curl)) { 138 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // FIXME 139 | curl_setopt($curl, CURLOPT_HEADER, true); 140 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 141 | curl_setopt($curl, CURLINFO_HEADER_OUT, true); 142 | 143 | if (($timeout = $httpConnection->getTimeout()) != null) { 144 | curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); 145 | } 146 | 147 | if (($connectionTimeout = $httpConnection->getConnectionTimeout()) != 148 | null) { 149 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 150 | $connectionTimeout); 151 | } 152 | 153 | $headers = array(); 154 | 155 | foreach ($this->requestHeader as $header) { 156 | $headers[] = sprintf('%s: %s', $header['name'], 157 | $header['value']); 158 | } 159 | 160 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 161 | 162 | $this->curlResource = $curl; 163 | $this->httpConnection = $httpConnection; 164 | $this->openned = true; 165 | } else { 166 | throw new RuntimeException('cURL failed to start'); 167 | } 168 | } else { 169 | throw new RuntimeException('cURL not found.'); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/Resource/MoipResource.php: -------------------------------------------------------------------------------- 1 | moip = $moip; 39 | $this->data = new stdClass(); 40 | $this->initialize(); 41 | } 42 | 43 | /** 44 | * Create a new connecttion. 45 | * 46 | * @return \Zabaala\Moip\Http\HTTPConnection 47 | */ 48 | protected function createConnection() 49 | { 50 | return $this->moip->createConnection(new HTTPConnection()); 51 | } 52 | 53 | /** 54 | * Get a key of an object if it exists. 55 | * 56 | * @param string $key 57 | * @param \stdClass|null $data 58 | * 59 | * @return mixed 60 | */ 61 | protected function getIfSet($key, stdClass $data = null) 62 | { 63 | if (empty($data)) { 64 | $data = $this->data; 65 | } 66 | 67 | if (isset($data->$key)) { 68 | return $data->$key; 69 | } 70 | 71 | return; 72 | } 73 | 74 | protected function getIfSetDateFmt($key, $fmt, stdClass $data = null) 75 | { 76 | $val = $this->getIfSet($key, $data); 77 | if (!empty($val)) { 78 | $dt = \DateTime::createFromFormat($fmt, $val); 79 | 80 | return $dt ? $dt : null; 81 | } 82 | 83 | return; 84 | } 85 | 86 | /** 87 | * Get a key, representing a date (Y-m-d), of an object if it exists. 88 | * 89 | * @param string $key 90 | * @param stdClass|null $data 91 | * 92 | * @return \DateTime|null 93 | */ 94 | protected function getIfSetDate($key, stdClass $data = null) 95 | { 96 | return $this->getIfSetDateFmt($key, 'Y-m-d', $data); 97 | } 98 | 99 | /** 100 | * Get a key representing a datetime (\Datetime::ATOM), of an object if it exists. 101 | * 102 | * @param string $key 103 | * @param stdClass|null $data 104 | * 105 | * @return \DateTime|null 106 | */ 107 | protected function getIfSetDateTime($key, stdClass $data = null) 108 | { 109 | return $this->getIfSetDateFmt($key, \DateTime::ATOM, $data); 110 | } 111 | 112 | /** 113 | * Specify data which should be serialized to JSON. 114 | * 115 | * @return \stdClass 116 | */ 117 | public function jsonSerialize() 118 | { 119 | return $this->data; 120 | } 121 | 122 | /** 123 | * Transform resource in a Illuminate\Support\Collection. 124 | * 125 | * @param $array 126 | * @return Collection 127 | */ 128 | protected function collect($array) 129 | { 130 | foreach ($array as $key => $value) { 131 | if (is_array($value)) { 132 | $value = $this->collect($value); 133 | $array[$key] = $value; 134 | } 135 | } 136 | 137 | return Collection::make($array); 138 | 139 | } 140 | 141 | /** 142 | * Find by path. 143 | * 144 | * @param string $path 145 | * @param bool $all If true, get all data. 146 | * @return stdClass 147 | * @throws \Exception 148 | */ 149 | public function getByPath($path, $all = false) 150 | { 151 | $httpConnection = $this->createConnection(); 152 | $httpConnection->addHeader('Content-Type', 'application/json'); 153 | 154 | $httpResponse = $httpConnection->execute($path, HTTPRequest::GET); 155 | 156 | if ($httpResponse->getStatusCode() != 200 && $httpResponse->getStatusCode() != 201) { 157 | throw new \Exception($httpResponse->getStatusMessage(), $httpResponse->getStatusCode()); 158 | } 159 | 160 | $responseContent = json_decode($httpResponse->getContent(), false); 161 | 162 | if($all) { 163 | return $responseContent; 164 | } 165 | 166 | return $this->collect($responseContent); 167 | } 168 | 169 | /** 170 | * Get all data by path. 171 | * 172 | * @param $path 173 | * @return stdClass 174 | */ 175 | public function getAllByPath($path) { 176 | return $this->getByPath($path, true); 177 | } 178 | 179 | /** 180 | * Make a Moip Resource. 181 | * 182 | * @param string $path 183 | * @param string $method 184 | * @return stdClass 185 | * @throws \Exception 186 | */ 187 | protected function makeResource($path, $method = HTTPRequest::POST) 188 | { 189 | $body = json_encode($this, JSON_UNESCAPED_SLASHES); 190 | 191 | $httpConnection = $this->createConnection(); 192 | $httpConnection->addHeader('Content-Type', 'application/json'); 193 | $httpConnection->addHeader('Content-Length', strlen($body)); 194 | $httpConnection->setRequestBody($body); 195 | 196 | $httpResponse = $httpConnection->execute($path, $method); 197 | 198 | $response = new MoipResponse($this, $httpResponse); 199 | 200 | if ($httpResponse->getStatusCode() != 200 && $httpResponse->getStatusCode() != 201) { 201 | $error = $response->byCode($httpResponse->getStatusCode()); 202 | 203 | if (!empty($error->all())) { 204 | throw new \Exception($error->last(), $httpResponse->getStatusCode()); 205 | } 206 | 207 | throw new \Exception('[Moip] ' . $httpResponse->getStatusMessage(), $httpResponse->getStatusCode()); 208 | 209 | } 210 | 211 | return !is_null($httpResponse->getContent()) && !empty($httpResponse->getContent()) 212 | ? json_decode($httpResponse->getContent(), false) 213 | : null; 214 | } 215 | 216 | /** 217 | * Create a new Moip Resource. 218 | * 219 | * @param $path 220 | * @return stdClass 221 | */ 222 | public function createResource($path) { 223 | return $this->makeResource($path); 224 | } 225 | 226 | /** 227 | * Update a Moip Resource. 228 | * 229 | * @param $path 230 | * @return stdClass 231 | */ 232 | public function updateResource($path) { 233 | return $this->makeResource($path, HTTPRequest::PUT); 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/Http/HTTPCookieManager.php: -------------------------------------------------------------------------------- 1 | cookies = $cookieManager->cookies; 50 | } 51 | } 52 | 53 | $this->cookieFile = $cookieFile; 54 | } else { 55 | throw new RuntimeException('Permission denied at '.$dirname); 56 | } 57 | } 58 | 59 | /** 60 | * Destroi o objeto e salva os cookies armazenados. 61 | */ 62 | public function __destruct() 63 | { 64 | if ($this->cookieFile != null) { 65 | file_put_contents($this->cookieFile, serialize($this)); 66 | } 67 | } 68 | 69 | /** 70 | * @see CookieManager::addCookie() 71 | */ 72 | public function addCookie(Cookie $cookie) 73 | { 74 | $cookieDomain = $cookie->getDomain(); 75 | 76 | if (!isset($this->cookies[$cookieDomain])) { 77 | $this->cookies[$cookieDomain] = array(); 78 | } 79 | 80 | $this->cookies[$cookieDomain][] = $cookie; 81 | } 82 | 83 | /** 84 | * @see CookieManager::getCookie() 85 | */ 86 | public function getCookie($domain, $secure, $path) 87 | { 88 | return implode('; ', $this->getCookieArray($domain, $secure, $path)); 89 | } 90 | 91 | /** 92 | * @param string $domain 93 | * @param bool $secure 94 | * @param string $path 95 | */ 96 | private function getCookieArray($domain, $secure, $path) 97 | { 98 | $cookies = array(); 99 | $secure = $secure === true; 100 | 101 | if (isset($this->cookies[$domain])) { 102 | foreach ($this->cookies[$domain] as $cookie) { 103 | if ($cookie->isSecure() == $secure && $cookie->getPath() == $path) { 104 | $cookies[] = $cookie; 105 | } 106 | } 107 | } 108 | 109 | return $cookies; 110 | } 111 | 112 | /** 113 | * @see CookieManager::getCookieIterator() 114 | */ 115 | public function getCookieIterator($domain, $secure, $path) 116 | { 117 | return new ArrayIterator($this->getCookieArray($domain, $secure, $path)); 118 | } 119 | 120 | /** 121 | * @see CookieManager::setCookie() 122 | */ 123 | public function setCookie($setCookie, $domain = null) 124 | { 125 | if (is_array($setCookie)) { 126 | foreach ($setCookie as $setCookieItem) { 127 | $this->setCookie($setCookieItem); 128 | } 129 | } else { 130 | $matches = array(); 131 | 132 | if (preg_match( 133 | '/(?[^\=]+)\=(?[^;]+)'. 134 | '(; expires=(?[^;]+))?'. 135 | '(; path=(?[^;]+))?'.'(; domain=(?[^;]+))?'. 136 | '(; (?secure))?'.'(; (?httponly))?/', 137 | $setCookie, $matches)) { 138 | $cookieName = null; 139 | $cookieValue = null; 140 | $cookieExpires = INF; 141 | $cookiePath = '/'; 142 | $cookieDomain = $domain; 143 | $cookieSecure = false; 144 | 145 | foreach ($matches as $key => $value) { 146 | if (!empty($value)) { 147 | switch ($key) { 148 | case 'name': 149 | $cookieName = $value; 150 | break; 151 | case 'value': 152 | $cookieValue = $value; 153 | break; 154 | case 'expires': 155 | $cookieExpires = strtotime($value); 156 | break; 157 | case 'path': 158 | $cookiePath = $value; 159 | break; 160 | case 'domain': 161 | $cookieDomain = $value; 162 | break; 163 | case 'secure': 164 | $cookieSecure = true; 165 | break; 166 | } 167 | } 168 | } 169 | 170 | if (!isset($this->cookies[$cookieDomain])) { 171 | $this->cookies[$cookieDomain] = array(); 172 | } 173 | 174 | $this->cookies[$cookieDomain][] = new Cookie($cookieName, 175 | $cookieValue, $cookieDomain, $cookieExpires, $cookiePath, 176 | $cookieSecure); 177 | } 178 | } 179 | } 180 | 181 | /** 182 | * @see Serializable::serialize() 183 | */ 184 | public function serialize() 185 | { 186 | return serialize($this->cookies); 187 | } 188 | 189 | /** 190 | * @see Serializable::unserialize() 191 | */ 192 | public function unserialize($serialized) 193 | { 194 | $cookies = unserialize($serialized); 195 | 196 | if (is_array($cookies)) { 197 | $now = time(); 198 | 199 | foreach ($cookies as $domain => $domainCookies) { 200 | foreach ($domainCookies as $cookie) { 201 | $this->unserializeCookie($cookie, $domain); 202 | } 203 | } 204 | } 205 | } 206 | 207 | /** 208 | * @param \Zabaala\Moip\Http\Cookie $cookie 209 | * @param string|int $domain 210 | */ 211 | public function unserializeCookie($cookie, $domain) 212 | { 213 | if ($cookie instanceof Cookie && $cookie->getExpires() > $now) { 214 | if (!isset($this->cookies[$domain])) { 215 | $this->cookies[$domain] = array(); 216 | } 217 | 218 | $this->cookies[$domain][] = $cookie; 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/Resource/Subscription.php: -------------------------------------------------------------------------------- 1 | data = new stdClass(); 48 | $this->data->customer = new stdClass(); 49 | } 50 | 51 | /** 52 | * Set subscription code. 53 | * 54 | * @param $code 55 | */ 56 | public function setCode($code) { 57 | $this->data->code = $code; 58 | } 59 | 60 | /** 61 | * Set subscription amount. 62 | * 63 | * @param $amount 64 | */ 65 | public function setAmount($amount) { 66 | $this->data->amount = $amount; 67 | } 68 | 69 | /** 70 | * Set Payment Method. 71 | * 72 | * @param string $method 73 | */ 74 | public function setPaymentMethod($method = Payment::METHOD_CREDIT_CARD) { 75 | $this->data->payment_method = $method; 76 | } 77 | 78 | /** 79 | * Set Plan Code. 80 | * 81 | * @param $planCode 82 | */ 83 | public function setPlanCode($planCode) { 84 | $plan = new stdClass(); 85 | $plan->code = $planCode; 86 | 87 | $this->data->plan = $plan; 88 | } 89 | 90 | /** 91 | * Set date to the next invoice. 92 | * 93 | * @param $day 94 | * @param $month 95 | * @param $year 96 | */ 97 | public function setNextInvoiceDate($day, $month, $year) { 98 | $date = new stdClass(); 99 | $date->day = $day; 100 | $date->month = $month; 101 | $date->year = $year; 102 | 103 | $this->data->next_invoice_date = $date; 104 | } 105 | 106 | /** 107 | * Set code of coupon. 108 | * 109 | * @param $code 110 | */ 111 | public function setCouponCode($code) { 112 | $coupon = new stdClass(); 113 | $coupon->code = $code; 114 | $this->data->coupon = $coupon; 115 | } 116 | 117 | /** 118 | * Get all Subscriptions. 119 | * 120 | * @return stdClass 121 | */ 122 | public function all() 123 | { 124 | return $this->getByPath(sprintf('/%s/?limit=20000', self::PATH), true); 125 | } 126 | 127 | /** 128 | * Find a Subscription. 129 | * 130 | * @param string $code 131 | * 132 | * @return stdClass 133 | */ 134 | public function get($code) 135 | { 136 | return $this->getByPath(sprintf('/%s/%s', self::PATH, $code)); 137 | } 138 | 139 | /** 140 | * Sort Subscription creation. 141 | * 142 | * @return stdClass 143 | */ 144 | public function create() { 145 | return $this->createResource(sprintf('/%s', self::PATH)); 146 | } 147 | 148 | /** 149 | * Sort Subscription creation. 150 | * 151 | * @return stdClass 152 | */ 153 | public function createWithNewSubscriber() { 154 | return $this->createResource(sprintf('/%s?new_customer=true', self::PATH)); 155 | } 156 | 157 | /** 158 | * Update a Subscription. 159 | * 160 | * @return stdClass 161 | */ 162 | public function update() { 163 | return $this->updateResource(sprintf('/%s/%s', self::PATH, $this->data->code)); 164 | } 165 | 166 | /** 167 | * Activate a Subscription. 168 | */ 169 | public function activate() { 170 | return $this->setStatus(self::STATUS_ACTIVATED); 171 | } 172 | 173 | /** 174 | * Suspend a Subscription. 175 | * If suspended, the subscription will be charged at the end of the current range, 176 | * to reactivate it, the next will be charged according to the signing of the contract date. 177 | */ 178 | public function suspend() { 179 | return $this->setStatus(self::STATUS_SUSPENDED); 180 | } 181 | 182 | /** 183 | * Cancel a Subscription. 184 | * When a Subscription is canceled, it can't be reactivated. 185 | */ 186 | public function cancel() { 187 | return $this->setStatus(self::STATUS_CANCELED); 188 | } 189 | 190 | /** 191 | * Define situation of Subscription. 192 | * 193 | * @param $status 194 | * @return stdClass 195 | */ 196 | protected function setStatus($status) { 197 | return $this->updateResource(sprintf('/%s/%s/%s', self::PATH, $this->data->code, $status)); 198 | } 199 | 200 | /** 201 | * Set Code of the Subscriber. 202 | * 203 | * @param $code 204 | * 205 | * @return $this 206 | */ 207 | public function setSubscriberCode($code) 208 | { 209 | $this->data->customer->code = $code; 210 | 211 | return $this; 212 | } 213 | 214 | /** 215 | * Set e-mail of the Subscriber. 216 | * 217 | * @param string $email Email Subscriber. 218 | * 219 | * @return $this 220 | */ 221 | public function setSubscriberEmail($email) 222 | { 223 | $this->data->customer->email = $email; 224 | 225 | return $this; 226 | } 227 | 228 | /** 229 | * Set fullname of the Subscriber. 230 | * 231 | * @param string $fullname Customer's full name. 232 | * 233 | * @return $this 234 | */ 235 | public function setSubscriberFullName($fullname) 236 | { 237 | $this->data->customer->fullname = $fullname; 238 | 239 | return $this; 240 | } 241 | 242 | /** 243 | * Set fullname of the Subscriber. 244 | * 245 | * @param $cpf 246 | * 247 | * @return $this 248 | */ 249 | public function setSubscriberCpf($cpf) 250 | { 251 | $this->data->customer->cpf = $cpf; 252 | 253 | return $this; 254 | } 255 | 256 | /** 257 | * Set phone of the Subscriber. 258 | * 259 | * @param int $areaCode DDD telephone. 260 | * @param int $number Telephone number. 261 | * 262 | * @return $this 263 | */ 264 | public function setSubscriberPhone($areaCode, $number) 265 | { 266 | $this->data->customer->phone_area_code = $areaCode; 267 | $this->data->customer->phone_number = $number; 268 | 269 | return $this; 270 | } 271 | 272 | /** 273 | * Set birth date of the Subscriber. 274 | * 275 | * @param $day 276 | * @param $month 277 | * @param $year 278 | * 279 | * @return $this 280 | */ 281 | public function setSubscriberBirthDate($day, $month, $year) 282 | { 283 | $this->data->customer->birthdate_day = $day; 284 | $this->data->customer->birthdate_month = $month; 285 | $this->data->customer->birthdate_year = $year; 286 | 287 | return $this; 288 | } 289 | 290 | /** 291 | * Add a new address to the Subscriber. 292 | * 293 | * @param string $street 294 | * @param string $number 295 | * @param string $district 296 | * @param string $city 297 | * @param string $state 298 | * @param string $zip 299 | * @param string $complement 300 | * @param string $country 301 | * 302 | * @return $this 303 | */ 304 | public function setSubscriberAddress( 305 | $street, 306 | $number, 307 | $complement = null, 308 | $district, 309 | $city, 310 | $state, 311 | $zip, 312 | $country = self::ADDRESS_COUNTRY 313 | ) 314 | { 315 | $address = new stdClass(); 316 | $address->street = $street; 317 | $address->number = $number; 318 | $address->complement = $complement; 319 | $address->district = $district; 320 | $address->city = $city; 321 | $address->state = $state; 322 | $address->country = $country; 323 | $address->zipcode = $zip; 324 | 325 | $this->data->customer->address = $address; 326 | 327 | return $this; 328 | } 329 | 330 | /** 331 | * Set credit card of the Subscriber. 332 | * 333 | * @param int $number Card number. 334 | * @param int $expirationMonth Card expiration month. 335 | * @param int $expirationYear Year card expiration. 336 | * @param $holder_name 337 | * 338 | * @return $this 339 | */ 340 | public function setSubscriberCreditCard( 341 | $number, 342 | $expirationMonth, 343 | $expirationYear, 344 | $holder_name 345 | ) 346 | { 347 | $credit_card = new stdClass(); 348 | $credit_card->number = $number; 349 | $credit_card->holder_name = $holder_name; 350 | $credit_card->expiration_month = $expirationMonth; 351 | $credit_card->expiration_year = $expirationYear; 352 | 353 | $this->data->customer->billing_info = new stdClass(); 354 | $this->data->customer->billing_info->credit_card = $credit_card; 355 | 356 | return $this; 357 | } 358 | 359 | } 360 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](https://poser.pugx.org/zabaala/moip/v/stable)](https://packagist.org/packages/zabaala/moip) 2 | [![Total Downloads](https://poser.pugx.org/zabaala/moip/downloads)](https://packagist.org/packages/zabaala/moip) 3 | [![Latest Unstable Version](https://poser.pugx.org/zabaala/moip/v/unstable)](https://packagist.org/packages/zabaala/moip) 4 | [![License](https://poser.pugx.org/zabaala/moip/license)](https://packagist.org/packages/zabaala/moip) 5 | 6 | # Moip Assinaturas 7 | 8 | Permita que sua aplicação Laravel se integre com o servico de pagamento recorrente do Moip. 9 | 10 | > Pacote criado a partir do SDK V2 criado pela Moiplabs. 11 | 12 | ### Instalando o pacote 13 | 14 | Para incluir a última versão estável do pacote, execute o seguinte comando: 15 | 16 | ```bash 17 | composer require zabaala/moip 18 | ``` 19 | 20 | Você pode optar também por utilizar versões não estáveis do pacote, o que te permitirá utilizar recursos que ainda estão em desenvolvimento ou em teste. 21 | 22 | Para isso, execute: 23 | 24 | ```bash 25 | composer require zabaala/moip:dev-develop 26 | ``` 27 | 28 | Depois de incluir a dependência `zabaala/moip` no seu projeto, você vai precisar adicionar o Service Provider e um Aliase do pacote no seu arquivo `config/app.php`. No final, você deve ter algo semelhante ao código a baixo: 29 | 30 | ```php 31 | 'providers' => [ 32 | ... 33 | Zabaala\Moip\MoipServiceProvider::class, 34 | ... 35 | ], 36 | 37 | 'aliases' => [ 38 | ... 39 | 'Moip' => Zabaala\Moip\MoipFacade::class, 40 | ... 41 | ], 42 | ``` 43 | 44 | ### Configurando o Pacote 45 | 46 | O pacote `zabaala/moip` possue um arquivo de configuração que precisa ser publicado para a pasta de configuração raiz do seu projeto Laravel. Para isto, execute o comando: 47 | ```php 48 | php artisan vendor:publish --tag=moip 49 | ``` 50 | 51 | Ao final do processo, você encontrará um arquivo chamado `moip.php` dentro da pasta `config/` do seu projeto. 52 | 53 | Neste momento você vai precisar configurar o seu pacote. Antes de continuar com a configuração, é importante que você já tenha uma conta criada com o Moip. Caso você ainda não possua uma conta Moip tenha, acesse http://cadastro.moip.com.br e efetue seu cadastro. Após você efetuar seu cadastro e tiver a certeza de que sua conta está ativa, autentique-se no ambiente do Moip. 54 | 55 | O Moip possue dois End Points: 56 | 1. Production: Ambiente final de integração ou Ambiente de Produção. Aqui suas operações serão feitas com dados reais e serão processadas pelo Moip. 57 | 2. Sandbox: Ambiente de teste de integração. Aqui suas operações são salvas no moip, mas não são submetidas às operadoras de cartões de crédito. 58 | 59 | Por padrão, o pacote utiliza o End Point `sandbox` como padrão em suas configurações. 60 | 61 | Uma outra informação importante também, é que o pacote estimula a paramatrização saudável da sua aplicação. Por isso, embora exista um arquivo `moip.php` na sua pasta configurações, recomendo fortemente que você parametrize essas configurações no seu arquivo `.env`. Então, para isso, basta incluir as seguintes linhas no final do seu arquivo `.env`: 62 | 63 | ``` 64 | MOIP_CLIENT=Client Name 65 | MOIP_ENDPOINT=sandbox 66 | MOIP_API_TOKEN=[your-api-token] 67 | MOIP_API_KEY=[your-api-key] 68 | ``` 69 | 70 | Defina os valores corretos para cada uma das variaveis de ambiente relacionadas acima. 71 | 72 | ## Utilizando o pacote 73 | 74 | Com esse pacote você poderá: 75 | * **Planos (Plan):** (listar, consultar, criar, ativar, desativar); 76 | * **Cupons (Coupon):** (listar, consultar, criar, ativar, desativar); 77 | * **Assinantes (Subscriber):** (listar, consultar, criar, atualizar); 78 | * **Informações de Cobrança (BillingInfo):** (Atualizar dados de cobrança); 79 | * **Assinaturas (Subscription):** (Criar, listar, consultar detalhes, suspender, reativar, cancelar, alterar); 80 | * **Faturas (Invoice):** (Listar, consultar); 81 | * **Pagamentos (Payment):** (Listar, consultar); 82 | * **Números de Cartões de Crédito para testes**. 83 | 84 | ### Planos (Plans) 85 | 86 | Listando os planos existentes: 87 | 88 | ```php 89 | $moip = Moip::plans()->all(); 90 | ``` 91 | 92 | Consultando um plano: 93 | 94 | ```php 95 | $moip = Moip::plans()->find($code); 96 | ``` 97 | 98 | Criando um plano: 99 | 100 | ```php 101 | $plans = Moip::plans(); 102 | $plans->setCode('PLAN-123-7789'); 103 | $plans->setName("PLANO 01"); 104 | $plans->setDescription("Plano básico de assinatura"); 105 | $plans->setAmount("3000"); // Corresponde à R$ 30,00 106 | $plans->setInterval('MONTH', 1); // Recorrência da cobrança 107 | $plans->setPaymentMethod(\Zabaala\Moip\Resource\Payment::METHOD_CREDIT_CARD); 108 | 109 | try { 110 | $plans->create(); 111 | } catch (RuntimeException $e) { 112 | echo $e->getMessage(); 113 | } 114 | ``` 115 | 116 | Alterando um plano: 117 | 118 | ```php 119 | $plans = Moip::plans(); 120 | $plans->setCode('PLAN-UNIQ-CODE'); 121 | $plans->setName("PLANO 01"); 122 | $plans->setDescription("Plano básico de assinatura"); 123 | $plans->setAmount("3000"); // Corresponde à R$ 30,00 124 | $plans->setInterval('MONTH', 1); // Recorrência da cobrança 125 | $plans->setPaymentMethod(\Zabaala\Moip\Resource\Payment::METHOD_CREDIT_CARD); 126 | 127 | try { 128 | $plans->update(); 129 | } catch (RuntimeException $e) { 130 | echo $e->getMessage(); 131 | } 132 | ``` 133 | 134 | Ativando um plano: 135 | 136 | ```php 137 | $moip = Moip::plans(); 138 | $plans->setCode('PLAN-UNIQ-CODE'); 139 | 140 | try { 141 | $plans->activate(); 142 | } catch (RuntimeException $e) { 143 | echo $e->getMessage(); 144 | } 145 | ``` 146 | 147 | Desativando um plano um plano: 148 | 149 | ```php 150 | $plans = Moip::plans(); 151 | $plans->setCode('PLAN-UNIQ-CODE'); 152 | 153 | try { 154 | $plans->inactivate(); 155 | } catch (RuntimeException $e) { 156 | echo $e->getMessage(); 157 | } 158 | ``` 159 | 160 | ### Cupons (Coupons) 161 | 162 | Listando todos os cupons de desconto: 163 | 164 | ```php 165 | $coupons = Moip::coupons()->all(); 166 | ``` 167 | 168 | Criando um novo cupom de desconto: 169 | 170 | ```php 171 | $coupons = Moip::coupons(); 172 | $coupons->setCode('ABCD-1234'); 173 | $coupons->setName('Coupon de teste de integração'); 174 | $coupons->setDescription('Utilizado para testar a integração com o Moip'); 175 | $coupons->setDiscount('20', 'percent'); 176 | $coupons->setStatus('active'); 177 | $coupons->setDuration('once'); // once|repeating|forever 178 | $coupons->setMaxRedemptions('100'); 179 | $coupons->setExpirationDate('31', '12', '2016'); 180 | 181 | try { 182 | $coupons->create(); 183 | } catch (\Exception $e) { 184 | throw new \Exception($e); 185 | } 186 | ``` 187 | 188 | Ativando um plano: 189 | 190 | ```php 191 | $coupons = Moip::coupons(); 192 | $coupons->setCode('ABCD-1234'); 193 | $coupons->activate(); 194 | ``` 195 | 196 | Desativando um plano: 197 | 198 | ```php 199 | $coupons = Moip::coupons(); 200 | $coupons->setCode('ABCD-1234'); 201 | $coupons->inactivate(); 202 | ``` 203 | 204 | ### Assinantes (Subscribers) 205 | 206 | Listando todos os assinantes: 207 | 208 | ```php 209 | $subscriber = Moip::subscribers(); 210 | $subscriber->all(); 211 | ``` 212 | 213 | Consultando um assinante: 214 | 215 | ```php 216 | $moip = Moip::subscribers(); 217 | $subscriber->get('CLIENT-CODE'); 218 | ``` 219 | 220 | Criando um novo assinante: 221 | 222 | ```php 223 | $subscriber = Moip::subscribers(); 224 | $subscriber->setCode('CLIENT-CODE'); 225 | $subscriber->setEmail('emaildocliente@domain.com'); 226 | $subscriber->setFullName("FULANO DE TAL"); 227 | $subscriber->setCpf("00000000000"); // Sem mascara. 228 | $subscriber->setPhone(/* code area */ '11', /* phone number */ '999999999'); // Sem mascara. 229 | $subscriber->setBirthDate(/* Day */ '31', /* Month */ '12', /* Year */ '1990'); 230 | $subscriber->setAddress( 231 | 'AVENIDA CORONEL LINHARES', // street. 232 | '4565', // number. 233 | 'AP 304', // complement. Can be null. 234 | 'CENTRO', // District. 235 | 'SAO PAULO', // City. 236 | 'SP', // State. 237 | '01000000' // Zipcode. 238 | ); 239 | 240 | try { 241 | $subscriber->create(); 242 | } catch (RuntimeException $e) { 243 | echo $e->getMessage(); 244 | } 245 | ``` 246 | 247 | Atualizando um assinante: 248 | 249 | ```php 250 | $subscriber = Moip::subscribers(); 251 | $subscriber->setCode('CLIENT-CODE'); 252 | $subscriber->setEmail('emaildocliente@domain.com'); 253 | $subscriber->setFullName("FULANO DE TAL"); 254 | $subscriber->setCpf("00000000000"); // Sem mascara. 255 | $subscriber->setPhone(/* code area */ '11', /* phone number */ '999999999'); // Sem mascara. 256 | $subscriber->setBirthDate(/* Day */ '31', /* Month */ '12', /* Year */ '1990'); 257 | $subscriber->setAddress( 258 | 'AVENIDA CORONEL LINHARES', // street. 259 | '4565', // number. 260 | 'AP 304', // complement. Can be null. 261 | 'CENTRO', // District. 262 | 'SAO PAULO', // City. 263 | 'SP', // State. 264 | '01000000' // Zipcode. 265 | ); 266 | 267 | try { 268 | $subscriber->update(); 269 | } catch (RuntimeException $e) { 270 | echo $e->getMessage(); 271 | } 272 | ``` 273 | 274 | ### Informações de cobrança (BillingInfo) 275 | 276 | Atualizando o cartão de crédito de um determinado assinante: 277 | 278 | ```php 279 | $billingInfo = Moip::billingInfos(); 280 | $billingInfo->setSubscriberCode('CLIENT-CODE'); 281 | $billingInfo->setCreditCard( 282 | '0000000000000000', // credit card number. 283 | '08', // expiration day. 284 | '20', // expiration year with two digits. 285 | 'FULANO C DE TAL' // holder name. 286 | ); 287 | 288 | try { 289 | $billingInfo->update(); 290 | } catch (RuntimeException $e) { 291 | echo $e->getMessage(); 292 | } 293 | ``` 294 | 295 | ### Assinaturas (Subscriptions) 296 | 297 | Listando todas as assinaturas: 298 | 299 | ```php 300 | $subscription = Moip::subscriptions(); 301 | $subscription->get('SUBSCRIPTION-CODE'); 302 | ``` 303 | 304 | Consultando uma assinatura: 305 | 306 | ```php 307 | $moip = Moip::subscriptions(); 308 | $subscription->get('SUBSCRIPTION-CODE'); 309 | ``` 310 | 311 | Criando uma assinatura: 312 | 313 | ```php 314 | $subscription = Moip::subscriptions(); 315 | $subscription->setCode(uniqid()); 316 | $subscription->setAmount('3000'); 317 | $subscription->setPaymentMethod(\MoipAssinaturas\Resource\Payment::METHOD_CREDIT_CARD); 318 | $subscription->setPlanCode('PLAN-CODE'); 319 | $subscription->setSubscriberCode('02'); 320 | 321 | try { 322 | $subscription->create(); 323 | } catch (RuntimeException $e) { 324 | echo $e->getMessage(); 325 | } 326 | ``` 327 | 328 | Alterando uma assinatura: 329 | 330 | ```php 331 | $subscription = Moip::subscriptions(); 332 | $subscription->setCode('SUBSCRIPTION-CODE'); 333 | $subscription->setPlanCode('PLAN-CODE'); 334 | $subscription->setNextInvoiceDate(/* day */ '05', /* month */ '03', /* year with 4 digits */ '2016'); 335 | 336 | try { 337 | $subscription->update(); 338 | } catch (RuntimeException $e) { 339 | echo $e->getMessage(); 340 | } 341 | ``` 342 | 343 | ### Faturas (Invoice) 344 | 345 | Listando todas as faturas: 346 | 347 | ```php 348 | $invoice = Moip::invoices(); 349 | $invoice->setSubscriptionCode('SUBSCRIPTION-CODE'); 350 | $invoice->all(); 351 | ``` 352 | Consultando uma assinatura: 353 | 354 | ```php 355 | $invoice = Moip::invoices(); 356 | $invoice->get('INVOICE-CODE'); 357 | ``` 358 | 359 | ### Pagamentos (Payments) 360 | 361 | Listando todos os pagamentos: 362 | 363 | ```php 364 | $payments = Moip::payments(); 365 | $payments->setInvoiceCode('INVOICE-CODE'); 366 | $payments->all(); 367 | ``` 368 | 369 | Consultando um pagamento: 370 | 371 | ```php 372 | $payments = Moip::payments(); 373 | $payments->get('PAYMENT-ID'); 374 | ``` 375 | 376 | ### Cartões de Créditos para teste 377 | 378 | Abaixo seguem alguns números de cartões de crédito que podem ser utilizados para teste: 379 | 380 | ``` 381 | American Express*: 376411112222331 382 | Mastercard: 5555666677778884 383 | Diners: 30111122223331 384 | Visa: 4073020000000002 385 | Hipercard: 3841009009123456089 386 | ``` 387 | 388 | *O cartão American Express possui CVV de 4 dígitos, ao contrário de todas as bandeiras que possuem CVV com apenas 3. 389 | 390 | ### Licensa 391 | MIT License. -------------------------------------------------------------------------------- /src/Http/HTTPConnection.php: -------------------------------------------------------------------------------- 1 | addHeaderRequest($name, $value, $override); 125 | } 126 | 127 | /** 128 | * Limpa os campos de cabeçalho e de requisição definidos anteriormente. 129 | * 130 | * @see \Zabaala\Moip\Http\HTTPConnection::clearHeaders() 131 | * @see \Zabaala\Moip\Http\HTTPConnection::clearParameters() 132 | */ 133 | public function clear() 134 | { 135 | $this->clearHeaders(); 136 | $this->clearParameters(); 137 | } 138 | 139 | /** 140 | * Limpa os campos de cabeçalhos definidos anteriormente. 141 | */ 142 | public function clearHeaders() 143 | { 144 | $this->requestHeader = array(); 145 | } 146 | 147 | /** 148 | * Limpa os campos definidos anteriormente. 149 | */ 150 | public function clearParameters() 151 | { 152 | $this->requestParameter = array(); 153 | } 154 | 155 | /** 156 | * Fecha a conexão. 157 | * 158 | * @throws \BadMethodCallException Se não houver uma conexão inicializada. 159 | */ 160 | public function close() 161 | { 162 | $this->initialized = false; 163 | } 164 | 165 | /** 166 | * Verifica se existe um header e retorna o seu valor. 167 | * 168 | * @param string $key 169 | * 170 | * @return string 171 | */ 172 | private function getHeader($key) 173 | { 174 | if (isset($this->requestHeader[$key])) { 175 | $header = $this->requestHeader[$key]['value']; 176 | 177 | unset($this->requestHeader[$key]); 178 | } else { 179 | if ($key === 'host') { 180 | $header = $this->getHost(); 181 | } elseif ($key === 'accept') { 182 | $header = '*/*'; 183 | } elseif ($key === 'user-agent') { 184 | $header = self::$userAgent; 185 | } 186 | } 187 | 188 | return $header; 189 | } 190 | 191 | /** 192 | * Executa a requisição a requisição HTTP em um caminho utilizando um 193 | * método específico. 194 | * 195 | * @param string $path Caminho da requisição. 196 | * @param string $method Método da requisição. 197 | * 198 | * @return string Resposta HTTP. 199 | * 200 | * @throws \BadMethodCallException Se não houver uma conexão inicializada ou se o objeto de requisição não for válido. 201 | */ 202 | public function execute($path = '/', $method = HTTPRequest::GET) 203 | { 204 | $request = $this->newRequest(); 205 | 206 | if ($request instanceof HTTPRequest) { 207 | $request->addRequestHeader('Host', $this->getHeader('host')); 208 | $request->addRequestHeader('Accept', $this->getHeader('accept')); 209 | $request->addRequestHeader('User-Agent', $this->getHeader('user-agent')); 210 | 211 | if ($this->httpAuthenticator != null) { 212 | $request->authenticate($this->httpAuthenticator); 213 | } 214 | 215 | foreach ($this->requestHeader as $header) { 216 | $request->addRequestHeader($header['name'], $header['value']); 217 | } 218 | 219 | $cookieManager = $this->getCookieManager(); 220 | 221 | if ($cookieManager != null) { 222 | $cookies = $cookieManager->getCookie($this->getHostName(), 223 | $this->isSecure(), $path); 224 | 225 | if (isset($this->requestHeader['cookie'])) { 226 | $buffer = $this->requestHeader['cookie']['value'].'; '. 227 | $cookies; 228 | } else { 229 | $buffer = $cookies; 230 | } 231 | 232 | $request->addRequestHeader('Cookie', $buffer); 233 | } 234 | 235 | foreach ($this->requestParameter as $name => $value) { 236 | $request->setParameter($name, $value); 237 | } 238 | 239 | $request->setRequestBody($this->requestBody); 240 | 241 | if ($path == null || !is_string($path) || empty($path)) { 242 | $path = '/'; 243 | } elseif (substr($path, 0, 1) != '/') { 244 | $path = '/'.$path; 245 | } 246 | 247 | if ($this->timeout != null) { 248 | $request->setTimeout($this->timeout); 249 | } 250 | 251 | if ($this->connectionTimeout != null) { 252 | $request->setConnectionTimeout($this->connectionTimeout); 253 | } 254 | 255 | $request->open($this); 256 | $request->execute($path, $method); 257 | 258 | return $request->getResponse(); 259 | } else { 260 | throw new BadMethodCallException('Invalid request object.'); 261 | } 262 | } 263 | 264 | /** 265 | * Recupera o timeout de conexão. 266 | * 267 | * @return int 268 | */ 269 | public function getConnectionTimeout() 270 | { 271 | return $this->connectionTimeout; 272 | } 273 | 274 | /** 275 | * Recupera o gerenciador de Cookies. 276 | * 277 | * @return \Zabaala\Moip\Http\CookieManager 278 | */ 279 | public function getCookieManager() 280 | { 281 | return $this->cookieManager; 282 | } 283 | 284 | /** 285 | * Recupera o host da conexão. 286 | * 287 | * @return string 288 | * 289 | * @throws \BadMethodCallException Se a conexão não tiver sido inicializada. 290 | */ 291 | public function getHost() 292 | { 293 | if ($this->initialized) { 294 | $hostname = $this->getHostName(); 295 | 296 | if (($this->secure && $this->port != self::HTTPS_PORT) || 297 | (!$this->secure && $this->port != self::HTTP_PORT)) { 298 | $hostname .= ':'.$this->port; 299 | } 300 | 301 | return $hostname; 302 | } 303 | 304 | throw new BadMethodCallException('Connection not initialized'); 305 | } 306 | 307 | /** 308 | * Recupera o nome do host. 309 | * 310 | * @return string 311 | * 312 | * @throws \BadMethodCallException Se não houver uma conexão inicializada. 313 | */ 314 | public function getHostName() 315 | { 316 | if ($this->initialized) { 317 | return $this->hostname; 318 | } 319 | 320 | throw new BadMethodCallException('Connection not initialized'); 321 | } 322 | 323 | /** 324 | * Recupera a porta que será utilizada na conexão. 325 | * 326 | * @return int 327 | * 328 | * @throws \BadMethodCallException Se não houver uma conexão inicializada. 329 | */ 330 | public function getPort() 331 | { 332 | if ($this->initialized) { 333 | return $this->port; 334 | } 335 | 336 | throw new BadMethodCallException('Connection not initialized'); 337 | } 338 | 339 | /** 340 | * Recupera o timeout. 341 | * 342 | * @return int 343 | */ 344 | public function getTimeout() 345 | { 346 | return $this->timeout; 347 | } 348 | 349 | /** 350 | * Recupera a URI que será utilizada na conexão. 351 | * 352 | * @return string 353 | * 354 | * @throws \BadMethodCallException Se não houver uma conexão inicializada. 355 | */ 356 | public function getURI() 357 | { 358 | if ($this->initialized) { 359 | return sprintf('%s://%s', $this->isSecure() ? 'https' : 'http', 360 | $this->getHost()); 361 | } 362 | 363 | throw new BadMethodCallException('Connection not initialized'); 364 | } 365 | 366 | /** 367 | * Inicializa a conexão HTTP. 368 | * 369 | * @param string $hostname Servidor que receberá a requisição. 370 | * @param bool $secure Indica se a conexão será segura (https). 371 | * @param int $port Porta da requisição. 372 | * @param int $connectionTimeout Timeout de conexão em segundos. 373 | * @param int $timeout Timeout de espera em segundos. 374 | */ 375 | public function initialize($hostname, $secure = false, 376 | $port = self::HTTP_PORT, $connectionTimeout = 0, $timeout = 0) 377 | { 378 | if ($this->initialized) { 379 | $this->close(); 380 | } 381 | 382 | $this->initialized = true; 383 | $this->hostname = $hostname; 384 | $this->secure = $secure === true; 385 | 386 | if (func_num_args() == 2) { 387 | $this->port = $this->secure ? self::HTTPS_PORT : self::HTTP_PORT; 388 | } else { 389 | $this->port = (int) $port; 390 | } 391 | 392 | $this->connectionTimeout = (int) $connectionTimeout; 393 | $this->timeout = (int) $timeout; 394 | } 395 | 396 | /** 397 | * Verifica se é uma conexão segura. 398 | * 399 | * @return bool 400 | */ 401 | public function isSecure() 402 | { 403 | return $this->secure === true; 404 | } 405 | 406 | /** 407 | * Cria uma instância de um objeto de requisição HTTP. 408 | * 409 | * @return \Moip\Http\HTTPRequest 410 | */ 411 | public function newRequest() 412 | { 413 | return new CURL(); 414 | } 415 | 416 | /** 417 | * Define um autenticador HTTP. 418 | * 419 | * @param \Zabaala\Moip\Http\HTTPAuthenticator $httpAuthenticator 420 | */ 421 | public function setAuthenticator(HTTPAuthenticator $httpAuthenticator) 422 | { 423 | $this->httpAuthenticator = $httpAuthenticator; 424 | } 425 | 426 | /** 427 | * Define o timeout de conexão. 428 | * 429 | * @param int $connectionTimeout 430 | * 431 | * @throws \InvalidArgumentException Se $connectionTimeout não for um inteiro. 432 | */ 433 | public function setConnectionTimeout($connectionTimeout) 434 | { 435 | if (is_integer($connectionTimeout)) { 436 | $this->connectionTimeout = $connectionTimeout; 437 | } else { 438 | throw new InvalidArgumentException( 439 | 'Connection timeout must be specified in seconds.'); 440 | } 441 | } 442 | 443 | /** 444 | * Define um gerenciador de cookies para essa conexão. 445 | * 446 | * @param \Zabaala\Moip\Http\CookieManager $cookieManager 447 | */ 448 | public function setCookieManager(CookieManager $cookieManager) 449 | { 450 | $this->cookieManager = $cookieManager; 451 | } 452 | 453 | /** 454 | * Define um parâmetro que será enviado com a requisição, um parâmetro é um 455 | * par nome-valor que será enviado como uma query string. 456 | * 457 | * @param string $name Nome do parâmetro. 458 | * @param string $value Valor do parâmetro. 459 | * 460 | * @throws \InvalidArgumentException Se o nome ou o valor do campo não forem valores scalar. 461 | */ 462 | public function setParam($name, $value = null) 463 | { 464 | if (is_scalar($name) && (is_scalar($value) || is_null($value))) { 465 | $this->requestParameter[$name] = $value; 466 | } else { 467 | throw new InvalidArgumentException('Name and value MUST be scalar'); 468 | } 469 | } 470 | 471 | /** 472 | * Define o corpo da requisição. 473 | * 474 | * @param string $requestBody 475 | */ 476 | public function setRequestBody($requestBody) 477 | { 478 | $this->requestBody = $requestBody; 479 | } 480 | 481 | /** 482 | * Define o timeout. 483 | * 484 | * @param int $timeout 485 | * 486 | * @throws \InvalidArgumentException Se $timeout não for um inteiro. 487 | */ 488 | public function setTimeout($timeout) 489 | { 490 | if (is_integer($timeout)) { 491 | $this->timeout = $timeout; 492 | } else { 493 | throw new InvalidArgumentException( 494 | 'Timeout must be specified in seconds.'); 495 | } 496 | } 497 | } 498 | --------------------------------------------------------------------------------