2011-12-25 6 views
0

저는 약간의 지불 옵션을 가져야하는 소규모 웹샵을 개발 중입니다. 내 플랫폼은 Google App Engine 및 Python 2.7입니다. django/python 인 satchmo라는 프로젝트가 있으며 코드를 사용할 수 있을지 궁금합니다.GAE에서 파이썬 2.7을 사용하는 webshop에 대한 지불 처리는 무엇입니까?

class PaymentOption(models.Model): 
    """ 
    If there are multiple options - CC, Cash, COD, etc this class allows 
    configuration. 
    """ 
    description = models.CharField(_("Description"), max_length=20) 
    active = models.BooleanField(_("Active"), 
     help_text=_("Should this be displayed as an option for the user?")) 
    optionName = models.CharField(_("Option Name"), max_length=20, choices=iterchoices_db(payment.config.labelled_gateway_choices), 
     unique=True, 
     help_text=_("The class name as defined in payment.py")) 
    sortOrder = models.IntegerField(_("Sort Order")) 

    class Meta: 
     verbose_name = _("Payment Option") 
     verbose_name_plural = _("Payment Options") 

class CreditCardDetail(models.Model): 
    """ 
    Stores an encrypted CC number, its information, and its 
    displayable number. 
    """ 
    orderpayment = models.ForeignKey('shop.OrderPayment', unique=True, 
     related_name="creditcards") 
    credit_type = models.CharField(_("Credit Card Type"), max_length=16, choices=iterchoices_db(payment.config.credit_choices)) 
    display_cc = models.CharField(_("CC Number (Last 4 digits)"), 
     max_length=4,) 
    encrypted_cc = models.CharField(_("Encrypted Credit Card"), 
     max_length=40, blank=True, null=True, editable=False) 
    expire_month = models.IntegerField(_("Expiration Month")) 
    expire_year = models.IntegerField(_("Expiration Year")) 
    card_holder = models.CharField(_("card_holder Name"), max_length=60, blank=True) 
    start_month = models.IntegerField(_("Start Month"), blank=True, null=True) 
    start_year = models.IntegerField(_("Start Year"), blank=True, null=True) 
    issue_num = models.CharField(blank=True, null=True, max_length=2) 

    def storeCC(self, ccnum): 
     """Take as input a valid cc, encrypt it and store the last 4 digits in a visible form""" 
     self.display_cc = ccnum[-4:] 
     encrypted_cc = _encrypt_code(ccnum) 
     if config_value('PAYMENT', 'STORE_CREDIT_NUMBERS'): 
      self.encrypted_cc = encrypted_cc 
     else: 
      standin = "%s%i%i%i" % (self.display_cc, self.expire_month, self.expire_year, self.orderpayment.id) 
      self.encrypted_cc = _encrypt_code(standin) 
      key = _encrypt_code(standin + '-card') 
      keyedcache.cache_set(key, skiplog=True, length=60*60, value=encrypted_cc) 

    def setCCV(self, ccv): 
     """Put the CCV in the cache, don't save it for security/legal reasons.""" 
     if not self.encrypted_cc: 
      raise ValueError('CreditCardDetail expecting a credit card number to be stored before storing CCV') 

     keyedcache.cache_set(self.encrypted_cc, skiplog=True, length=60*60, value=ccv) 

    def getCCV(self): 
     try: 
      ccv = keyedcache.cache_get(self.encrypted_cc) 
     except keyedcache.NotCachedError: 
      ccv = "" 

     return ccv 

    ccv = property(fget=getCCV, fset=setCCV) 

    def _decryptCC(self): 
     ccnum = _decrypt_code(self.encrypted_cc) 
     if not config_value('PAYMENT', 'STORE_CREDIT_NUMBERS'): 
      try: 
       key = _encrypt_code(ccnum + '-card') 
       encrypted_ccnum = keyedcache.cache_get(key) 
       ccnum = _decrypt_code(encrypted_ccnum) 
      except keyedcache.NotCachedError: 
       ccnum = "" 
     return ccnum 

    decryptedCC = property(_decryptCC) 

    def _expireDate(self): 
     return(str(self.expire_month) + "/" + str(self.expire_year)) 
    expirationDate = property(_expireDate) 

    class Meta: 
     verbose_name = _("Credit Card") 
     verbose_name_plural = _("Credit Cards") 

def _decrypt_code(code): 
    """Decrypt code encrypted by _encrypt_code""" 
    # In some blowfish implementations, > 56 char keys can cause problems 
    secret_key = settings.SECRET_KEY[:56] 
    encryption_object = Blowfish.new(secret_key) 
    # strip padding from decrypted credit card number 
    return encryption_object.decrypt(base64.b64decode(code)).rstrip('X') 

def _encrypt_code(code): 
    """Quick encrypter for CC codes or code fragments""" 
    # In some blowfish implementations, > 56 char keys can cause problems 
    secret_key = settings.SECRET_KEY[:56] 
    encryption_object = Blowfish.new(secret_key) 
    # block cipher length must be a multiple of 8 
    padding = '' 
    if (len(code) % 8) <> 0: 
     padding = 'X' * (8 - (len(code) % 8)) 
    return base64.b64encode(encryption_object.encrypt(code + padding)) 

코드는 엔진을 앱에 휴대용보고 내가 원하는 경우 I 또는 수도 포트를이 코드는, 생각하고 츠모 (Satchmo) 프로젝트는 이미 많은 해결해야 : Here은 지불에 대한 모델 중 일부에 대한 오픈 소스입니다 내 webshop을 구현할 때 직면하게 될 문제는 무엇입니까? 또는 실제로 app 엔진에서 satchmo를 실행하는 것과 비슷한 질문에서 제안 된 것처럼 "장고에 대한 우호적 인 호스팅"을 추가로 얻어야합니까?

답변

3

많은 연구를하고있는 것처럼 많은 사람들이 이것을 시도하고 포기한 것처럼 보입니다. 앱 엔진에서 satchmo를 실행하는 데는 몇 가지 문제가 있습니다. 대부분 모델 및 종속성과 관련이 있지만 PCI 규정 준수 문제도 있습니다.

먼저 PCI 측면을 다룰 것입니다 - 귀하의 계정에 플러그를 꽂으려는 상인 계정 공급자의 염려없이 신용 카드 데이터를 저장할 수 있으려면 PCI DSS를 준수해야합니다. 신용 카드 데이터와 상호 작용하려는 경우 보안 표준을 설정하기 위해 변호사 (하!)가 작성한 문서입니다. CVV2 (카드 뒷면에 3 자리 코드)를 절대 저장하지 않는 등 좋은 모범 사례입니다. 그러나 한 가지 중요한 점은 사용 된 스토리지의 보안과 관련이 있습니다. Google은이를 광고하지 않지만 App Engine과 자사의 독점적 인 DB가 PCI와 호환되지 않는다고 확신합니다. 이것은 당신이 위에 쌓아 올린 어떤 것이라도 PCI와 호환되지 않는다는 것을 의미합니다.

이제 기술 측면. 내가 읽은 것부터이 작업을하는 가장 좋은 방법은 django_nonrel입니다. 외장 키에 의존하지 않도록 일부 모델을 수정해야합니다. 또한 reportlab과 같은 몇 가지 다른 종속성이 있습니다. 여기, http://groups.google.com/group/satchmo-developers/browse_thread/thread/f14053df13232615

그리고 마지막으로 유래에 대한 기존의 논의이다 : 여기서 그 얘기 게시물입니다 How to make Satchmo work in Google App Engine

일반적인 합의가 츠모 (Satchmo)이 GAE에 적합하지 않다는 것이다. 선반 솔루션으로는 좋지 않지만 페이팔을 살펴 보시기 바랍니다. https://www.x.com/devzone/articles/using-paypals-adaptive-payments-and-google-app-engine-build-online-market-python

또한이 코드는 사용자가 필요로하는 코드에 맞게 조정될 수 있습니다. 그들은 구글 체크 아웃을 사용하고 있습니다 : https://stripe.com/

행운을 빕니다 : http://code.google.com/p/chippysshop/

마지막으로, 신용 카드 거래의 모든 종류를 처리하고 상인 계정을 필요로하지 않는 스트라이프를,있다!

+0

답변 해 주셔서 감사합니다. GAE에 대한 Paypal 예제는 Python 2.5 SDK를 사용하여 나를 위해 작동합니다. 그러나 ithython 2.7로 업그레이드 할 때 별도의 질문으로 게시 한 오류 메시지가 나타납니다. –