public static function pay($invest, &$errors = array()) { if ($invest->status == 1) { $errors[] = 'Este aporte ya está cobrado!'; @mail(\GOTEO_FAIL_MAIL, 'Dobleejecución de preapproval', 'Se intentaba ejecutar un aporte en estado Cobrado. <br /><pre>' . print_r($invest, 1) . '</pre>'); return false; } try { $project = Project::getMini($invest->project); $userData = User::getMini($invest->user); // al productor le pasamos el importe del cargo menos el 8% que se queda goteo $amountPay = $invest->amount - $invest->amount * 0.08; // Create request object $payRequest = new \PayRequest(); $payRequest->memo = "Cargo del aporte de {$invest->amount} EUR del usuario '{$userData->name}' al proyecto '{$project->name}'"; $payRequest->cancelUrl = SITE_URL . '/invest/charge/fail/' . $invest->id; $payRequest->returnUrl = SITE_URL . '/invest/charge/success/' . $invest->id; $payRequest->clientDetails = new \ClientDetailsType(); $payRequest->clientDetails->customerId = $invest->user; $payRequest->clientDetails->applicationId = PAYPAL_APPLICATION_ID; $payRequest->clientDetails->deviceId = PAYPAL_DEVICE_ID; $payRequest->clientDetails->ipAddress = PAYPAL_IP_ADDRESS; $payRequest->currencyCode = 'EUR'; $payRequest->preapprovalKey = $invest->preapproval; $payRequest->actionType = 'PAY_PRIMARY'; $payRequest->feesPayer = 'EACHRECEIVER'; $payRequest->reverseAllParallelPaymentsOnError = true; // $payRequest->trackingId = $invest->id; // SENDER no vale para chained payments (PRIMARYRECEIVER, EACHRECEIVER, SECONDARYONLY) $payRequest->requestEnvelope = new \RequestEnvelope(); $payRequest->requestEnvelope->errorLanguage = 'es_ES'; // Primary receiver, Goteo Business Account $receiverP = new \receiver(); $receiverP->email = PAYPAL_BUSINESS_ACCOUNT; // tocar en config para poner en real $receiverP->amount = $invest->amount; $receiverP->primary = true; // Receiver, Projects PayPal Account $receiver = new \receiver(); $receiver->email = \trim($invest->account); $receiver->amount = $amountPay; $receiver->primary = false; $payRequest->receiverList = array($receiverP, $receiver); // Create service wrapper object $ap = new \AdaptivePayments(); // invoke business method on service wrapper passing in appropriate request params $response = $ap->Pay($payRequest); // Check response if (strtoupper($ap->isSuccess) == 'FAILURE') { $error_txt = ''; $soapFault = $ap->getLastError(); if (is_array($soapFault->error)) { $errorId = $soapFault->error[0]->errorId; $errorMsg = $soapFault->error[0]->message; } else { $errorId = $soapFault->error->errorId; $errorMsg = $soapFault->error->message; } if (is_array($soapFault->payErrorList->payError)) { $errorId = $soapFault->payErrorList->payError[0]->error->errorId; $errorMsg = $soapFault->payErrorList->payError[0]->error->message; } // tratamiento de errores switch ($errorId) { case '569013': // preapproval cancelado por el usuario desde panel paypal // preapproval cancelado por el usuario desde panel paypal case '539012': // preapproval no se llegó a autorizar if ($invest->cancel()) { $action = 'Aporte cancelado'; // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Aporte cancelado por preaproval cancelado por el usuario paypal', '/admin/accounts', \vsprintf('Se ha <span class="red">Cancelado</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s por preapproval cancelado', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); } break; case '569042': // cuenta del proyecto no confirmada en paypal // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Cuenta del proyecto no confirmada en PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque la cuenta del proyecto <span class="red">no está confirmada</span> en PayPal', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '580022': // uno de los mails enviados no es valido // uno de los mails enviados no es valido case '589039': // el mail del preaproval no está registrada en paypal // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('El mail del preaproval no esta registrado en PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque el mail del preaproval <span class="red">no está registrado</span> en PayPal', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '520009': // la cuenta esta restringida por paypal // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('La cuenta esta restringida por PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque la cuenta <span class="red">está restringida</span> por PayPal', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '579033': // misma cuenta que el proyecto // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Se ha usado la misma cuenta que del proyecto', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque la cuenta <span class="red">es la misma</span> que la del proyecto', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '579024': // fuera de fechas // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Está fuera del rango de fechas', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque estamos <span class="red">fuera del rango de fechas</span> del preapproval', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '579031': // The total amount of all payments exceeds the maximum total amount for all payments // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Problema con los importes', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque ha habido <span class="red">algun problema con los importes</span>', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; case '520002': // Internal error // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Error interno de PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s porque ha habido <span class="red">un error interno en PayPal</span>', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); break; default: if (empty($errorId)) { @mail(\GOTEO_FAIL_MAIL, 'Error fatal en comunicacion Paypal API', 'ERROR en ' . __FUNCTION__ . ' No es un soap fault pero no es un success.<br /><pre>' . print_r($ap, 1) . '</pre>'); $log = new Feed(); $log->setTarget($project->id); $log->populate('Error interno de PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s <span class="red">NO es soapFault pero no es Success</span>, se ha reportado el error.', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); } else { $log = new Feed(); $log->setTarget($project->id); $log->populate('Error interno de PayPal', '/admin/accounts', \vsprintf('Ha <span class="red">fallado al ejecutar</span> el aporte de %s de %s (id: %s) al proyecto %s del dia %s <span class="red">' . $action . ' ' . $errorMsg . ' [' . $errorId . ']</span>', array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin('system'); $error_txt = $log->title; unset($log); } break; } if (empty($errorId)) { $errors[] = 'NO es soapFault pero no es Success: <pre>' . print_r($ap, 1) . '</pre>'; } elseif (!empty($error_txt)) { $errors[] = $error_txt; } else { $errors[] = "{$action} {$errorMsg} [{$errorId}]"; } Invest::setIssue($invest->id); return false; } $token = $response->payKey; if (!empty($token)) { if ($invest->setPayment($token)) { if ($response->paymentExecStatus != 'INCOMPLETE') { Invest::setIssue($invest->id); $errors[] = "Error de Fuente de crédito."; return false; } $invest->setStatus(1); return true; } else { Invest::setIssue($invest->id); $errors[] = "Obtenido payKey: {$token} pero no se ha grabado correctamente (paypal::setPayment) en el registro id: {$invest->id}."; @mail(\GOTEO_FAIL_MAIL, 'Error al actualizar registro aporte (setPayment)', 'ERROR en ' . __FUNCTION__ . ' Metodo paypal::setPayment ha fallado.<br /><pre>' . print_r($response, 1) . '</pre>'); return false; } } else { Invest::setIssue($invest->id); $errors[] = 'No ha obtenido Payment Key.'; @mail(\GOTEO_FAIL_MAIL, 'Error en implementacion Paypal API (no payKey)', 'ERROR en ' . __FUNCTION__ . ' No payment key obtained.<br /><pre>' . print_r($response, 1) . '</pre>'); return false; } } catch (Exception $e) { $fault = new \FaultMessage(); $errorData = new \ErrorData(); $errorData->errorId = $ex->getFile(); $errorData->message = $ex->getMessage(); $fault->error = $errorData; Invest::setIssue($invest->id); $errors[] = 'No se ha podido inicializar la comunicación con Paypal, se ha reportado la incidencia.'; @mail(\GOTEO_FAIL_MAIL, 'Error fatal en comunicacion Paypal API', 'ERROR en ' . __FUNCTION__ . ' Exception<br /><pre>' . print_r($fault, 1) . '</pre>'); return false; } }