2009-04-25 7 views
20

Я пытаюсь реализовать функциональность IPN PayPal. Основной протокол таков:Интерфейс Python для PayPal - urllib.urlencode без символов ASCII с ошибкой

  1. Клиент перенаправляется с моего сайта на сайт PayPal для завершения платежа. Он входит в свой аккаунт, разрешает оплату.
  2. PayPal вызывает страницу на моем сервере, передавая детали как POST. Подробности включают имя человека, адрес и информацию о платежах и т. Д.
  3. Мне нужно вызвать URL-адрес на сайте PayPal из моей страницы обработки, передав все параметры, которые были переданы в abovem, и еще один, который называется cmd с значение '_notify-validate'.

Когда я пытаюсь urllib.urlencode в Params, который PayPal послал мне, я получаю:

While calling send_response_to_paypal. Traceback (most recent call last): 
    File "<snip>/account/paypal/views.py", line 108, in process_paypal_ipn 
    verify_result = send_response_to_paypal(params) 
    File "<snip>/account/paypal/views.py", line 41, in send_response_to_paypal 
    params = urllib.urlencode(params) 
    File "/usr/local/lib/python2.6/urllib.py", line 1261, in urlencode 
    v = quote_plus(str(v)) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 9: ordinal not in range(128) 

Я понимаю, что UrlEncode делает кодировку ASCII, а в некоторых случаях, пользователь контактной информации могут содержать символы, отличные от ASCII. Это понятно. Мой вопрос, как я могу кодировать не-ASCII символы для отправки сообщений в URL с помощью urllib2.urlopen (REQ) (или другой метод)

Подробности:

Я прочитал Params в первоначальном запросе PayPal в качестве следующим образом (GET для тестирования):

def read_ipn_params(request): 
    if request.POST: 
     params= request.POST.copy() 
     if "ipn_auth" in request.GET: 
      params["ipn_auth"]=request.GET["ipn_auth"] 
     return params 
    else: 
     return request.GET.copy() 

код я использую для отправки обратно запрос на PayPal на странице обработки является:

def send_response_to_paypal(params): 
    params['cmd']='_notify-validate' 
    params = urllib.urlencode(params) 
    req = urllib2.Request(PAYPAL_API_WEBSITE, params) 
    req.add_header("Content-type", "application/x-www-form-urlencoded") 
    response = urllib2.urlopen(req) 
    status = response.read() 
    if not status == "VERIFIED": 
     logging.warn("PayPal cannot verify IPN responses: " + status) 
     return False 

    return True 

Очевидно, проблема возникает только в том случае, если чье-то имя или адрес или другое поле, используемое для оплаты PayPal, не попадает в диапазон ASCII.

ответ

41

Попробуйте преобразовать словарь Params в UTF-8 первой ... UrlEncode, кажется, нравится это лучше, чем юникод:

params = urllib.urlencode(dict([k, v.encode('utf-8')] for k, v in params.items())) 

Конечно, это предполагает, что вход юникод. Если ваш вклад есть нечто иное, чем юникод, вы хотите, чтобы расшифровать его в юникод, а затем кодировать его:

params['foo'] = my_raw_input.decode('iso-8859-1') 
params = urllib.urlencode(dict([k, v.encode('utf-8')] for k, v in params.items())) 
+0

Вы были правы - это избавилось от исключения на URLEncode. Однако теперь PayPal дает мне недействительный ответ. Это такая боль ... –

+1

так что krys, они (paypal) документируют, какую кодировку они хотят, если это не utf-8? –

+0

Спасибо! Незначительная ошибка: есть слишком много в конце первого экзамена, который вы даете. –

6

Вместо кодирования в utf-8, следует кодировать то, что когда-либо PayPal использует для поста , Он доступен под ключом «charset» в форме paypal отправляет.

Так следующий код работает для меня:

data = dict([(k, v.encode(data['charset'])) for k, v in data.items()])

3

Я знаю, что это немного поздно, чтобы звонить здесь, но самое лучшее решение, которое я нашел, было даже не разобрать, что они были отдавать обратно. В django (не знаю, что вы используете) я смог получить необработанный запрос, который они отправили, который я передал дословно. Тогда речь шла только о том, чтобы на это надеть CMD-ключ.

Таким образом, никогда не имеет значения, какую кодировку они посылают вам, вы просто отправляете его обратно.

+0

Вы пробовали это с ответом IPN, который включает символы Unicode, такие как ñ, á, é и т. д.? Проблема возникает только с этими типами символов. –

 Смежные вопросы

  • Нет связанных вопросов^_^