I am using the PayPal Sandbox account. Python SDK PayPal-Python-SDK
I have successfully created a payment using credit card vaults (credit/debit cards) but unable to execute the payment getting error.
card = Card.objects.get(id = request.data['cardId'])
paypalrestsdk.configure({
"mode": settings.PAYPAL_MODE, # sandbox or live
"client_id": settings.PAYPAL_CLIENT_ID,
"client_secret": settings.PAYPAL_CLIENT_SECRET
})
payment = paypalrestsdk.Payment({
"intent": "sale",
"payer": {
"payment_method": "credit_card",
"funding_instruments": [{
"credit_card_token": {
"credit_card_id": card.token,
}
}]
},
"transactions": [{
"amount": {
"total": float(request.data['amount']),
"currency": "USD"
},
"description": "Payment by vaulted credit card."
}]
})
if payment.create():
print(payment.id)
print("Payment created successfully")
# ID of the payment. This ID is provided when creating payment.
payment = paypalrestsdk.Payment.find(payment.id)
# PayerID is required to approve the payment(card token).
if payment.execute({"payer_id": card.token}): # return True or False (card.token : added card token - CARD-7K172274P2897384FLZJ3VCC)
print("Payment[%s] execute successfully" % (payment.id))
else:
print(payment.error)
else:
print(payment.error)
the error I am getting :
Failed. Response status: 404. Response message: Not Found. Error message: {\"name\":\"INVALID_RESOURCE_ID\",\"message\":\"Requested resource ID was not found.\",\"information_link\":\"https://developer.paypal.com/docs/api/payments/#errors\",\"debug_id\":\"be43810866322\"}
Related
I've have a modal for submitting ticket to trello, everything is working great but i need to output in slack a message to the user that his ticket is published.
In the slack api documentation (chapter 'Listening for view submissions') i can read :
# Handle a view_submission request
#app.view("view_1")
def handle_submission(ack, body, client, view, logger):
user = body["user"]["id"]
When i try the same I've got a KeyError: 'user'. Without that line the code work great but I need the user to know that his ticket is published on Trello and provide him the link (and other informations)
EDIT : I've printed the body dict content and nothing about the user :
{
"id":"XXXXXXXXX",
"team_id":"XXXXXXXXX",
"type":"modal",
"private_metadata":"",
"callback_id":"ticket_submission",
"state":{
"values":{
"block_type":{
"type":{
"type":"static_select",
"selected_option":{
"text":{
"type":"plain_text",
"text":"Feature",
"emoji":true
},
"value":"feature"
}
}
},
"block_priority":{
"priority":{
"type":"static_select",
"selected_option":{
"text":{
"type":"plain_text",
"text":"Critical",
"emoji":true
},
"value":"critical"
}
}
},
"block_description":{
"description":{
"type":"plain_text_input",
"value":"This is the description"
}
},
}
},
"hash":"1674058454.YvY8jNKh",
"title":{
"type":"plain_text",
"text":"Create Ticket",
"emoji":true
},
"clear_on_close":false,
"notify_on_close":false,
"close":{
"type":"plain_text",
"text":"Cancel",
"emoji":true
},
"submit":{
"type":"plain_text",
"text":"Submit",
"emoji":true
},
"previous_view_id":"None",
"root_view_id":"XXXXXXXXX",
"app_id":"XXXXXXXXX",
"external_id":"",
"app_installed_team_id":"XXXXXXXXX",
"bot_id":"XXXXXXXXX"
}
body = {
"sender_batch_header": {
"recipient_type": "EMAIL",
"email_message": "SDK payouts test txn",
"note": "Enjoy your Payout!!",
"sender_batch_id": "Test_SDK_1",
"email_subject": "This is a test transaction from SDK"
},
"items": [{
"note": "Your " + str(form.nbr_athena.data) + "€ Payout!",
"amount": {
"currency": "EUR",
"value": str(form.nbr_athena.data)
},
"receiver": str(form.email_paypal.data),
"sender_item_id": "Test_txn_5"
}]
}
request_paypal = PayoutsPostRequest()
request_paypal.request_body(body)
# Call API with your client and get a response for your call
response = sdk_paypal_client.execute(request)
# If call returns body in response, you can get the deserialized version from the result attribute of the response
batch_id = response.result.batch_header.payout_batch_id
print(batch_id)
print(response)
flash("votre monnaie à bien était envoyé !!", "success")
payment.status = Status.Success.value
db.session.add(payment)
db.session.commit()
I tried to integrate the paypal sdk on my site, but when sending the request with this line response = sdk_paypal_client.execute (request)
I receive a deep copy error
TypeError: cannot serialize '_io.BufferedReader' object i tried stringify my request but it's not good
I want to test a simple Ethereum smart contract
ganache prints accounts in lower-case and web3 gives me an error:
web3.exceptions.InvalidAddress: ('Web3.py only accepts checksum addresses. The software that gave you this non-checksum address should be considered unsafe, please file it as a bug on their platform. Try using an ENS name instead. Or, if you must accept lower safety, use Web3.toChecksumAddress(lower_case_address).', '0xfcad0b19bb29d4674531d6f115237e16afce377c')
I then convert the address to mixed address using:
Web3.toChecksumAddress(the_lower_case_ganache_address)
and it rises an error:
File "/usr/local/lib/python3.7/site-packages/web3/contract.py", line 1385, in call_contract_function
raise BadFunctionCallOutput(msg) from e
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?
127.0.0.1 - - [25/Jan/2019 21:35:21] "POST /blockchain/user HTTP/1.1" 500 -
it's my python code:
def check_gender(data):
valid_list = ["male", "female"]
if data not in valid_list:
raise ValidationError(
'Invalid gender. Valid choices are'+ valid_list
)
class UserSchema(Schema):
name = fields.String(required=True)
gender = fields.String(required=True, validate=check_gender)
app = Flask(__name__)
# api to set new user every api call
#app.route("/blockchain/user", methods=['POST'])
def transaction():
w3.eth.defaultAccount = w3.eth.accounts[0]
with open("data.json", 'r') as f:
datastore = json.load(f)
abi = datastore["abi"]
contract_address = datastore["contract_address"]
# Create the contract instance with the newly-deployed address
user = w3.eth.contract(
address=contract_address, abi=abi,
)
body = request.get_json()
result, error = UserSchema().load(body)
if error:
return jsonify(error), 422
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
tx_hash = tx_hash.transact()
# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)
user_data = user.functions.getUser().call()
return jsonify({"data": user_data}), 200
if __name__ == '__main__':
app.run()
`
and the json file:
{
"abi": [
{
"constant": false,
"inputs": [
{
"name": "name",
"type": "string"
},
{
"name": "gender",
"type": "string"
}
],
"name": "setUser",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "getUser",
"outputs": [
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"contract_address": "0xFCAd0B19bB29D4674531d6f115237E16AfCE377c"
}
The error is stating that Ganache cannot find a deployed contract to interact with.
Your code seems valid, but the error likely occurs on this line:
tx_hash = user.functions.setUser(
result['name'], result['gender']
)
The code attempts to set the user, but cannot find a contract to interact with (even if the ABI and contract instance are valid).
If you are using Ganache, it is likely that you are redeploying the contract each time you run the code, so the following line will likely not be working, provided you are pulling from a static file:
contract_address = datastore["contract_address"]
You will need to dynamically get the contract address from Ganache if you are deploying it each time.
For some reason My App is not working on live mode using PayPal REST API. This is the error I get on my Apache server:
[:error] [pid 29701] WARNING:root:Not logging full request/response headers and body in live mode for compliance
Here is my code, I'm using Django:
def payPaypal(sku, price, ship_code):
has_paypal_error = False
paypal_approval_url = None
paypalrestsdk.configure({
'mode': settings.PAYPAL_STATUS, # live
'client_id': settings.PAYPAL_LIVE_CLIENT_ID,
'client_secret': settings.PAYPAL_LIVE_CLIENT_SECRET
})
payment = paypalrestsdk.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal" },
"redirect_urls": {
"return_url": "mysite_url/thanks",
"cancel_url": "mysite_url" },
"transactions": [ {
"amount": {
"total": price[ship_code].amount,
"currency": price[ship_code].currency },
"description": "my description.",
"item_list": {
"items": [ {
"name": "name description",
"sku": sku,
"quantity": "1",
"price": price[ship_code].amount,
"currency": price[ship_code].currency
}]
}
}]
})
if payment.create():
for link in payment.links:
if link.rel == "approval_url":
paypal_approval_url = link.href
else:
has_paypal_error = True
return has_paypal_error, paypal_approval_url
And inside my form:
elif cd['payment_type'] == "2": # PayPal
is_paypal = True
has_paypal_error, paypal_approval_url = payPaypal(sku, price, ship_code)
payment_error_msg = _('Something went wrong, please try again')
thanks.html
if request.method == 'GET' and request.GET.get('paymentId'):
paymentId = request.GET.get('paymentId')
payment = paypalrestsdk.Payment.find(paymentId)
payer_id = payment.payer.payer_info.payer_id
if payment.execute({"payer_id": payer_id}):
sendInvoiceEmailToUser(email_to_send_invoce, email_invoce_lang)
sendSuccessNotificationToCrew(email_crew)
return render(request, 'thanks.html')
Looking at the response going "live", it looks like the "approval_url" is correct:
[{'href': u'https://api.paypal.com/v1/payments/payment/PAY-######', 'method': u'GET', 'rel': u'self'},
{'href': u'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-####', 'method': u'REDIRECT', 'rel': u'approval_url'},
{'href': u'https://api.paypal.com/v1/payments/payment/PAY-####/execute', 'method': u'POST', 'rel': u'execute'}]
Live APP Settings
I found the problem, and it had nothing to do with PayPal.
I forgot to add the paypal domains in the ALLOWED_HOSTS in my settings.py from my Django App
ALLOWED_HOSTS = [ 'mysite.com.', '.paypal.com', 'paypal.com.' ]
I'm running the code below and it takes the user to PayPal to make a payment and then returns them to the return_url as expected. However the code doesn't execute any further and it doesn't execute the payment.
I have based my code on https://github.com/paypal/rest-api-sdk-python:
class PayPalHandler(tornado.web.RequestHandler):
def get(self):
logging.basicConfig(level=logging.INFO)
paypal.configure({
"mode": PAYPAL_MODE,
"client_id": PAYPAL_CLIENT_ID,
"client_secret": PAYPAL_CLIENT_SECRET})
payment = paypal.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal" },
"redirect_urls": {
"return_url": "http://127.0.0.1:8000/ty",
"cancel_url": "http://127.0.0.1:8000/" },
"transactions": [ {
"item_list": {
"items": [{
"name": "membership",
"price": "2.00",
"currency": "GBP",
"quantity": 1 }]},
"amount": {
"total": "2.00",
"currency": "GBP" },
"description": "One of membership fee." } ] } )
redirect_url = ""
if payment.create():
print("Payment[%s] created successfully"%(payment.id))
for link in payment.links:
if link.method == "REDIRECT":
redirect_url = link.href
print("Redirect for approval: %s"%(redirect_url))
return self.redirect(redirect_url)
else:
print("Error while creating payment.")
print(payment.error)
response = payment.to_dict()
print response
payment = paypal.Payment.find(payment.id)
if payment.execute({"payer_id": response['payer_id']}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
print payment.to_dict()
print userData
So in the example at https://devtools-paypal.com/guide/pay_paypal/python?success=true&token=EC-8JL96732FP068791F&PayerID=QQGSRNHDACTLJ. Step 5 is not happening and no response is sent from PayPal?
This is Avi from PayPal here. I am not super familiar with Tornado, but after the line return self.redirect(redirect_url) happens in your code, and returns the user to the return_url, in payment.execute({"payer_id": response['payer_id']}) are you getting the payer_id correctly? Payer_id is returned appended to the return_url as one of the parameters in the format http://<return_url>?token=EC-60U79048BN7719609&PayerID=7E7MGXCWTTKK2. Also, what is the status of the payment after you execute payment = paypal.Payment.find(payment.id). The other suggestion I would have is to see if print payment.error prints a useful debug message and a debug_id which paypal merchant technical services can use to look at the issue.
You need other url where papypal redirects when the payment had been successful, where you will receive the token and the PayerID. In that GET method, you can put this part of the code (pseudocode):
payerid_param = request.get('PayerID')
payment = paypal.Payment.find(db_payment.id)
if payment.execute({"payer_id": payerid_param}):
print ("Payment executed successfully")
else:
print(payment.error) # Error Hash
You will need to save the payment_id between calls.
Why you use
return self.redirect(redirect_url)
I think you can use just
self.redirect(redirect_url)
I've never seen return statement in Tornado handlers.