문제

PayPal IPN 기능을 구현하려고합니다. 기본 프로토콜은 다음과 같습니다.

  1. 고객은 지불을 완료하기 위해 내 사이트에서 PayPal 사이트로 리디렉션됩니다. 그는 자신의 계정에 로그인하고 지불을 승인합니다.
  2. PayPal은 내 서버의 페이지를 포스트로 전달하는 페이지를 호출합니다. 세부 사항은 개인의 이름, 주소 및 지불 정보 등이 포함됩니다.
  3. Abovem에서 전달 된 모든 매개 변수와 '_Notify-Validate'의 값을 가진 'CMD'라는 추가 매개 변수를 전달하는 처리 페이지에서 내부적으로 PayPal 사이트에서 URL을 호출해야합니다.

urllib.urlencode 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가 아닌 문자가 포함될 수 있음을 이해합니다. 이것은 이해할 수 있습니다. 내 질문은 Urllib2.urlopen (또는 기타 방법)을 사용하여 URL에 게시하기 위해 비 ASCII 문자를 인코딩하는 방법입니다.

세부:

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 범위에 속하지 않는 경우에만 발생합니다.

도움이 되었습니까?

해결책

Params Dictionary를 UTF-8로 변환 해보십시오 ... UrlenCode는 Unicode보다 더 좋아 보인다 :

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()))

다른 팁

인코딩하는 대신 utf-8, PayPal이 게시물에 사용하는 것을 인코딩해야합니다. PayPal Send 형식의 키 'charset'에서 사용할 수 있습니다.

그래서 다음 코드는 저에게 효과가있었습니다.

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

나는 그것이 여기에서 차임하기에 조금 늦었다는 것을 알고 있지만, 내가 찾은 가장 좋은 해결책은 그들이 돌려주는 것을 구문 분석조차하지 않는 것이 었습니다. Django에서 (당신이 무엇을 사용하고 있는지 모릅니다) 나는 그들이 보낸 원시 요청을받을 수 있었고, 나는 구두로 되돌아 갔다. 그런 다음 CMD 키를 그 위에 올리는 문제였습니다.

이렇게하면 그들이 당신에게 보내는 인코딩이 어떤 것이 중요하지 않으며, 당신은 바로 그것을 다시 보내고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top