private function processClientErrors(PhortunePaymentProvider $provider, $client_errors_raw)
 {
     $errors = array();
     $client_errors = null;
     try {
         $client_errors = phutil_json_decode($client_errors_raw);
     } catch (PhutilJSONParserException $ex) {
         $errors[] = pht('There was an error decoding error information submitted by the ' . 'client. Expected a JSON-encoded list of error codes, received: %s.', nonempty($client_errors_raw, pht('nothing')));
     }
     foreach (array_unique($client_errors) as $key => $client_error) {
         $client_errors[$key] = $provider->translateCreatePaymentMethodErrorCode($client_error);
     }
     foreach (array_unique($client_errors) as $client_error) {
         switch ($client_error) {
             case PhortuneErrCode::ERR_CC_INVALID_NUMBER:
                 $message = pht('The card number you entered is not a valid card number. Check ' . 'that you entered it correctly.');
                 break;
             case PhortuneErrCode::ERR_CC_INVALID_CVC:
                 $message = pht('The CVC code you entered is not a valid CVC code. Check that ' . 'you entered it correctly. The CVC code is a 3-digit or 4-digit ' . 'numeric code which usually appears on the back of the card.');
                 break;
             case PhortuneErrCode::ERR_CC_INVALID_EXPIRY:
                 $message = pht('The card expiration date is not a valid expiration date. Check ' . 'that you entered it correctly. You can not add an expired card ' . 'as a payment method.');
                 break;
             default:
                 $message = $provider->getCreatePaymentMethodErrorMessage($client_error);
                 if (!$message) {
                     $message = pht("There was an unexpected error ('%s') processing payment " . "information.", $client_error);
                     phlog($message);
                 }
                 break;
         }
         $errors[$client_error] = $message;
     }
     return $errors;
 }