Skip to content

Commit

Permalink
Merge pull request #49 from pagopa/IDP-2024-adjustment-new-api-trx
Browse files Browse the repository at this point in the history
  • Loading branch information
TommasoLencioni authored Oct 31, 2023
2 parents a202600 + babaab8 commit d594bfe
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 77 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: f71fa2c #v4.4.0
rev: c4a0b88 #v4.5.0
hooks:
- id: check-case-conflict
- id: check-docstring-first
Expand Down Expand Up @@ -29,6 +29,6 @@ repos:
- id: requirements-txt-fixer

- repo: https://github.com/asottile/reorder_python_imports
rev: b5d69d1 #v3.9.0
rev: a8eaa42 #v3.12.0
hooks:
- id: reorder-python-imports
46 changes: 19 additions & 27 deletions api/idpay.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def get_initiative_statistics(organization_id, initiative_id):

def get_initiative_statistics_merchant_portal(initiative_id, merchant_id):
return requests.get(
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.statistics.path}/merchant/portal/initiatives/{initiative_id}/statistics',
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.statistics.path}{settings.IDPAY.endpoints.merchant.path}/portal/initiatives/{initiative_id}/statistics',
headers={
'x-merchant-id': merchant_id,
},
Expand All @@ -181,23 +181,19 @@ def post_merchant_create_transaction_acquirer(initiative_id,
merchant_id: str = 'MERCHANTID',
acquirer_id: str = settings.idpay.acquirer_id,
apim_request_id: str = 'APIMREQUESTID',
mcc: str = '1234',
merchant_fiscal_code: str = '12345678901',
vat: str = '12345678901'):
mcc: str = '1234'):
response = requests.post(
f'{settings.base_path.IO}{settings.IDPAY.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}',
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.payment.internal_path}{settings.IDPAY.endpoints.payment.path}/',
headers={
'x-merchant-id': merchant_id,
'x-acquirer-id': acquirer_id,
'x-apim-request-id': apim_request_id,
'x-apim-request-id': apim_request_id
},
json={
'amountCents': amount_cents,
'idTrxAcquirer': uuid.uuid4().int,
'initiativeId': initiative_id,
'mcc': mcc,
'merchantFiscalCode': merchant_fiscal_code,
'vat': vat,
'mcc': mcc
},
)
return response
Expand All @@ -208,27 +204,24 @@ def get_transaction_detail(transaction_id,
acquirer_id: str = settings.idpay.acquirer_id,
):
response = requests.get(
f'{settings.base_path.IO}{settings.IDPAY.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/status/{transaction_id}',
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.payment.internal_path}{settings.IDPAY.endpoints.payment.path}/{transaction_id}/status',
headers={
'x-merchant-id': merchant_id,
'x-acquirer-id': acquirer_id,
'x-apim-request-id': 'TEST',
'x-acquirer-id': acquirer_id
}
)
return response


def put_merchant_confirms_payment(transaction_id,
merchant_id: str = 'MERCHANTID',
acquirer_id: str = settings.idpay.acquirer_id,
apim_request_id: str = 'APIMREQUESTID'
acquirer_id: str = settings.idpay.acquirer_id
):
response = requests.put(
f'{settings.base_path.IO}{settings.IDPAY.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/{transaction_id}/confirm',
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.payment.internal_path}{settings.IDPAY.endpoints.payment.path}/{transaction_id}/confirm',
headers={
'x-merchant-id': merchant_id,
'x-acquirer-id': acquirer_id,
'x-apim-request-id': apim_request_id
'x-acquirer-id': acquirer_id
}
)
return response
Expand Down Expand Up @@ -258,15 +251,13 @@ def put_authorize_payment(trx_code, token):

def delete_payment_merchant(transaction_id,
merchant_id: str = 'MERCHANTID',
acquirer_id: str = settings.idpay.acquirer_id,
apim_request_id: str = 'APIMREQUESTID'
acquirer_id: str = settings.idpay.acquirer_id
):
response = requests.delete(
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.payment.internal_path}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/{transaction_id}',
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.payment.internal_path}{settings.IDPAY.endpoints.payment.path}/{transaction_id}',
headers={
'x-merchant-id': merchant_id,
'x-acquirer-id': acquirer_id,
'x-apim-request-id': apim_request_id
'x-acquirer-id': acquirer_id
}
)
return response
Expand Down Expand Up @@ -436,7 +427,7 @@ def upload_merchant_csv(selfcare_token: str,
initiative_id: str,
merchants_payload: dict):
res = requests.put(
url=f'{settings.base_path.IO}{settings.IDPAY.domain}/merchant/initiative/{initiative_id}/upload',
url=f'{settings.base_path.IO}{settings.IDPAY.domain}{settings.IDPAY.endpoints.merchant.path}/initiative/{initiative_id}/upload',
files=merchants_payload,
headers={
'Authorization': f'Bearer {selfcare_token}'
Expand All @@ -447,19 +438,20 @@ def upload_merchant_csv(selfcare_token: str,
return res


def get_merchant_list(organization_id: str,
def get_merchant_list(selfcare_token: str,
initiative_id: str,
page: int = 0):
"""API to get initiative statistics.
:param organization_id: ID of the organization of interest.
:param selfcare_token: SelfCare token of the test organization.
:param initiative_id: ID of the initiative of interest.
:param page: Page of merchants to query.
:returns: the response of the call.
:rtype: requests.Response
"""
return requests.get(
f'{settings.base_path.IDPAY.internal}{settings.IDPAY.endpoints.merchant.path}{settings.IDPAY.domain}/merchant/organization/{organization_id}/initiative/{initiative_id}/merchants?page={page}',
f'{settings.base_path.IO}{settings.IDPAY.domain}{settings.IDPAY.endpoints.merchant.path}/initiative/{initiative_id}/merchants?page={page}',
headers={
'Authorization': f'Bearer {selfcare_token}',
'Content-Type': 'application/json',
},
timeout=settings.default_timeout
Expand Down Expand Up @@ -624,7 +616,7 @@ def put_payment_results(selfcare_token: str,
def get_initiative_info(selfcare_token: str,
initiative_id: str):
"""API to get information related to an initiative.
:param selfcare_token: token SelfCare.
:param selfcare_token: SelfCare token of the test organization.
:param initiative_id: ID of the initiative of interest.
:returns: the response of the call.
:rtype: requests.Response
Expand Down
15 changes: 7 additions & 8 deletions api/mil.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def post_merchant_create_transaction_acquirer_mil(initiative_id,
merchant_fiscal_code: str = '12345678901'):
cert = load_certificates()
response = requests.post(
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}',
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}',
cert=cert,
headers={
settings.API_KEY_HEADER: secrets.api_key.IDPAY_MIL_PRODUCT,
Expand All @@ -23,11 +23,10 @@ def post_merchant_create_transaction_acquirer_mil(initiative_id,
},
json={
'initiativeId': initiative_id,
'merchantFiscalCode': merchant_fiscal_code,
'idTrxAcquirer': uuid.uuid4().int,
'amountCents': amount_cents,
'mcc': mcc,
},
'mcc': mcc
}
)
return response

Expand All @@ -37,7 +36,7 @@ def get_initiative_list_mil(merchant_fiscal_code: str,
):
cert = load_certificates()
response = requests.get(
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/initiatives',
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.merchant.path}/initiatives',
cert=cert,
headers={
settings.API_KEY_HEADER: secrets.api_key.IDPAY_MIL_PRODUCT,
Expand All @@ -54,12 +53,12 @@ def get_transaction_detail_mil(transaction_id,
):
cert = load_certificates()
response = requests.get(
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/status/{transaction_id}',
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}/{transaction_id}/status',
cert=cert,
headers={
settings.API_KEY_HEADER: secrets.api_key.IDPAY_MIL_PRODUCT,
'x-merchant-fiscalcode': merchant_fiscal_code,
'x-acquirer-id': acquirer_id,
'x-acquirer-id': acquirer_id
}
)
return response
Expand All @@ -71,7 +70,7 @@ def delete_transaction_mil(transaction_id,
):
cert = load_certificates()
response = requests.delete(
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}{settings.IDPAY.endpoints.payment.qr_code.path}{settings.IDPAY.endpoints.payment.qr_code.merchant}/{transaction_id}',
f'{settings.base_path.CSTAR}{settings.IDPAY.domain}{settings.IDPAY.MIL.domain}{settings.IDPAY.endpoints.payment.path}/{transaction_id}',
cert=cert,
headers={
settings.API_KEY_HEADER: secrets.api_key.IDPAY_MIL_PRODUCT,
Expand Down
2 changes: 1 addition & 1 deletion bdd/features/ranking/transaction.feature
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Feature: A merchant creates a transaction and a citizen tries to confirm it duri
Then the transaction X is not created because it is out of valid period

Scenario: A merchant cannot generate a transaction during the grace period
Given the initiative is "Ranking_in_grace_period"
Given a new initiative "ranking_initiative"
And the random merchant 1 is onboard
And the ranking period ends
And the ranking is produced
Expand Down
39 changes: 6 additions & 33 deletions bdd/steps/discount_transaction_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,17 @@ def step_check_named_transaction_status(context, trx_name, expected_status):

if status == 'NOT CREATED FOR INVALID AMOUNT':
assert context.latest_create_transaction_response.status_code == 400
assert context.latest_create_transaction_response.json()['code'] == 'INVALID AMOUNT'
assert context.latest_create_transaction_response.json()[
'message'].startswith('Cannot create transaction with invalid amount: ')
assert context.latest_create_transaction_response.json()['code'] == 'PAYMENT_AMOUNT_NOT_VALID'
return

if status == 'NOT CREATED BECAUSE IT IS OUT OF VALID PERIOD':
assert context.latest_create_transaction_response.status_code == 400
assert context.latest_create_transaction_response.json()['code'] == 'INVALID DATE'
assert context.latest_create_transaction_response.json()[
'message'].startswith(f'Cannot create transaction out of valid period. Initiative startDate: ')
assert context.latest_create_transaction_response.status_code == 403
assert context.latest_create_transaction_response.json()['code'] == 'PAYMENT_INITIATIVE_INVALID_DATE'
return

if status == 'ALREADY AUTHORIZED':
assert context.latest_pre_authorization_response.status_code == 403
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_ALREADY_AUTHORIZED'
assert context.latest_pre_authorization_response.json()[
'message'] == f'Transaction with trxCode [{context.transactions[trx_name]["trxCode"]}] is already authorized'
return

elif status == 'CANCELLED':
Expand Down Expand Up @@ -192,8 +186,6 @@ def step_check_named_transaction_status(context, trx_name, expected_status):

assert trx_details['status'] == 'REJECTED'
assert context.latest_pre_authorization_response.json()['code'] == f'PAYMENT_GENERIC_REJECTED'
assert context.latest_pre_authorization_response.json()[
'message'] == f'Transaction with trxCode [{context.transactions[trx_name]["trxCode"]}] is rejected'
return

if status == 'NOT AUTHORIZED FOR BUDGET ERODED':
Expand All @@ -202,25 +194,16 @@ def step_check_named_transaction_status(context, trx_name, expected_status):
assert trx_details['status'] == 'REJECTED'

assert context.latest_pre_authorization_response.json()['code'] == f'PAYMENT_BUDGET_EXHAUSTED'
assert context.latest_pre_authorization_response.json()['message'].startswith(
f'Budget exhausted for user [')
assert context.latest_pre_authorization_response.json()['message'].endswith(
f'] and initiative [{context.initiative_id}]')
return

if status == 'ALREADY ASSIGNED':
assert context.latest_pre_authorization_response.status_code == 403

assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_USER_NOT_VALID'
assert context.latest_pre_authorization_response.json()[
'message'] == f'Transaction with trxCode [{context.transactions[trx_name]["trxCode"]}] is already assigned to another user'
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_ALREADY_ASSIGNED'
return

if status == 'EXCEEDING RATE LIMIT':
assert context.latest_authorization_response.status_code == 429
assert context.latest_authorization_response.json()['code'] == 'PAYMENT_TOO_MANY_REQUESTS'
assert context.latest_authorization_response.json()[
'message'] == f'Too many request on the ms reward'
return

assert False, 'Status not implemented'
Expand Down Expand Up @@ -397,42 +380,32 @@ def step_check_latest_pre_authorization_failed(context):
@then('the latest pre-authorization fails because the transaction cannot be found')
def step_check_latest_pre_authorization_failed_not_found(context):
assert context.latest_pre_authorization_response.status_code == 404
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_NOT_FOUND_EXPIRED'
assert context.latest_pre_authorization_response.json()['message'].startswith(
'Cannot find transaction with trxCode ')
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_NOT_FOUND_OR_EXPIRED'


@then('the latest pre-authorization fails because the user is suspended')
def step_check_latest_pre_authorization_failed_user_suspended(context):
curr_tokenized_fc = tokenize_fc(context.associated_citizen[context.latest_transaction_name])
assert context.latest_pre_authorization_response.status_code == 403
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_USER_SUSPENDED'
assert context.latest_pre_authorization_response.json()[
'message'] == f'The user has been suspended for initiative [{context.initiative_id}]'


@then('the latest pre-authorization fails because the citizen is not onboard')
def step_check_latest_pre_authorization_failed_citizen_not_onboard(context):
assert context.latest_pre_authorization_response.status_code == 403
assert context.latest_pre_authorization_response.json()['code'] == 'PAYMENT_USER_NOT_ONBOARDED'
assert context.latest_pre_authorization_response.json()[
'message'] == f'The user is not onboarded on initiative [{context.initiative_id}].'


@then('the latest authorization fails because the user is suspended')
def step_check_latest_pre_authorization_failed_user_suspended(context):
assert context.latest_authorization_response.status_code == 403
assert context.latest_authorization_response.json()['code'] == 'PAYMENT_USER_SUSPENDED'
assert context.latest_authorization_response.json()[
'message'] == f'The user has been suspended for initiative [{context.initiative_id}]'


@then('the latest authorization fails because the user did not pre-authorize the transaction')
def step_check_latest_pre_authorization_failed_missing_pre_auth(context):
assert context.latest_authorization_response.status_code == 400
assert context.latest_authorization_response.json()['code'] == 'PAYMENT_STATUS_NOT_VALID'
assert context.latest_authorization_response.json()[
'message'] == f'Cannot relate transaction in status CREATED'
assert context.latest_authorization_response.json()['code'] == 'PAYMENT_NOT_ALLOWED_FOR_TRX_STATUS'


@then('the latest authorization fails because the transaction cannot be found')
Expand Down
3 changes: 1 addition & 2 deletions bdd/steps/onboarding_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ def step_check_onboarding_status(context, citizen_name, status):
res = wallet(initiative_id=context.initiative_id, token=token_io)
assert res.status_code == 404
res = timeline(initiative_id=context.initiative_id, token=token_io)
assert res.status_code == 200
assert not res.json()['operationList']
assert res.status_code == 404

elif status == 'SUSPENDED':
expected_status = status
Expand Down
3 changes: 2 additions & 1 deletion settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ IDPAY:
processed: '/transactions/processed'
unprocessed: '/transactions'
merchant:
path: '/idpaymerchant'
path: '/merchant'
internal_path: '/idpaymerchant/idpay'
mock:
isee: '/mock/citizen/isee'
initiatives:
Expand Down
Loading

0 comments on commit d594bfe

Please sign in to comment.