ogone: use COMPLUS to transmit the transaction_id (#47536)

Now ORDERID will contain the orderid if it is given or the
transaction_id if there is no orderid.

response() is adapted to work with old and new reponse:
* old, there is no COMPLUS in the response, ORDERID is used as the
  transaction_id
* new, COMPLUS is present, its value is returned as response.order_id
  (which is in fact the transaction_id :/ )

Ref:
https://epayments-support.ingenico.com/fr/integration/all-sales-channels/integrate-with-e-commerce/guide#variable-feedback-parameters
https://epayments-support.ingenico.com/fr/integration/all-sales-channels/integrate-with-e-commerce/guide#form-parameters
This commit is contained in:
Benjamin Dauvergne 2020-10-10 13:33:08 +02:00
parent c9174c008f
commit a9516b5c64
2 changed files with 25 additions and 25 deletions

View File

@ -15,11 +15,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import hashlib
import string
import six
from six.moves.urllib import parse as urlparse
from decimal import Decimal, ROUND_HALF_UP
from six.moves.urllib import parse as urlparse
import hashlib
import six
import uuid
from .common import (
PaymentCommon, PaymentResponse, FORM, CANCELLED, PAID,
@ -525,19 +525,18 @@ class Payment(PaymentCommon):
raise NotImplementedError('unknown environment %s' % self.environment)
def request(self, amount, orderid=None, name=None, email=None,
language=None, description=None, **kwargs):
language=None, description=None, transaction_id=None,
**kwargs):
# use complus for transmitting and receiving the transaction_id see
# https://epayments-support.ingenico.com/fr/integration/all-sales-channels/integrate-with-e-commerce/guide#variable-feedback-parameters
# orderid is now only used for unicity of payments check (it's
# garanteed that no payment for the same ORDERID can happen during a 45
# days window, see
# https://epayments-support.ingenico.com/fr/integration/all-sales-channels/integrate-with-e-commerce/guide#form-parameters)
complus = transaction_id or uuid.uuid4().hex
if not orderid:
orderid = complus
reference = self.transaction_id(20, string.digits + string.ascii_letters)
# prepend order id in payment reference
if orderid:
if len(orderid) > 24:
raise ValueError('orderid length exceeds 25 characters')
reference = (
orderid
+ ORDERID_TRANSACTION_SEPARATOR
+ self.transaction_id(29 - len(orderid),
string.digits + string.ascii_letters))
language = language or self.language
# convertir en centimes
amount = Decimal(amount) * 100
@ -545,10 +544,11 @@ class Payment(PaymentCommon):
amount = amount.quantize(Decimal('1.'), rounding=ROUND_HALF_UP)
params = {
'AMOUNT': force_text(amount),
'ORDERID': reference,
'ORDERID': orderid,
'PSPID': self.pspid,
'LANGUAGE': language,
'CURRENCY': self.currency,
'COMPLUS': complus,
}
if self.normal_return_url:
params['ACCEPTURL'] = self.normal_return_url
@ -575,7 +575,7 @@ class Payment(PaymentCommon):
fields=[{'type': 'hidden',
'name': key,
'value': params[key]} for key in params])
return reference, FORM, form
return complus, FORM, form
def response(self, query_string, **kwargs):
if six.PY3:
@ -589,7 +589,8 @@ class Payment(PaymentCommon):
# py2: decode binary strings in query-string
for key in params:
params[key] = force_text(params[key], self.encoding)
reference = params['ORDERID']
orderid = params['ORDERID']
complus = params.get('COMPLUS')
transaction_id = params['PAYID']
status = params['STATUS']
error = params['NCERROR']
@ -621,11 +622,10 @@ class Payment(PaymentCommon):
status, error, params.get('NCERRORPLUS', ''))
result = ERROR
# extract reference from received order id
if ORDERID_TRANSACTION_SEPARATOR in reference:
reference, transaction_id = reference.split(ORDERID_TRANSACTION_SEPARATOR, 1)
return PaymentResponse(
result=result,
signed=signed,
bank_data=params,
order_id=reference,
order_id=complus or orderid,
transaction_id=transaction_id)

View File

@ -50,19 +50,19 @@ def test_request(params):
amount=amount,
orderid=order_id,
email='foo@example.com')
assert len(reference) == 30
assert reference.startswith(order_id)
assert len(reference) == 32
root = ET.fromstring(str(what))
assert root.tag == 'form'
assert root.attrib['method'] == 'POST'
assert root.attrib['action'] == ogone.ENVIRONMENT_TEST_URL
values = {
'CURRENCY': u'EUR',
'ORDERID': reference,
'ORDERID': order_id,
'PSPID': PSPID,
'EMAIL': 'foo@example.com',
'AMOUNT': amount.replace('.', ''),
'LANGUAGE': 'fr_FR',
'COMPLUS': reference,
}
values.update({'SHASIGN': ogone_backend.backend.sha_sign_in(values)})
for node in root: