---
title: Payment Processing
description: "## [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/)[https://developer.bitcoin.org/examples/payment_processing.html#payment-protocol](https://developer.bitcoin.org/examples/payment_processing.html#payment-protocol) To request payment using the [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/), you use an extended (but backwards-compatible) [“bitcoin:” URI](https://developer.bitcoin.org/terms.html#term-bitcoin-uri). For example: ![Warning icon](https://developer.bitcoin.org/_images/icon_warning.svg) **Warning:** The [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/) is considered to be deprecated and will be removed in a later version of Bitcoin Core. The…"
url: "https://bitcoindevelopers.org/docs/examples/payment-processing-example/"
updated: "2025-05-14"
category: Examples
---

# Payment Processing

## [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/)[https://developer.bitcoin.org/examples/payment_processing.html#payment-protocol](https://developer.bitcoin.org/examples/payment_processing.html#payment-protocol)

To request payment using the [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/), you use an extended (but backwards-compatible) [“bitcoin:” URI](https://developer.bitcoin.org/terms.html#term-bitcoin-uri). For example:

![Warning icon](https://developer.bitcoin.org/_images/icon_warning.svg) **Warning:** The [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/) is considered to be deprecated and will be removed in a later version of Bitcoin Core. The protocol has multiple security design flaws and implementation flaws in some wallets. Users will begin receiving deprecation warnings in Bitcoin Core version 0.18 when using [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) URI’s. Merchants should transition away from [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) to more secure options such as [BIP21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki). Merchants should never require [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) payments and should provide [BIP21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki) fallbacks.

```
bitcoin:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN\
?amount=0.10\
&Label=Example+Merchant\
&Message=Order+of+flowers+%26+chocolates\
&r=https://example.com/pay.php/invoice%3Dda39a3ee
```

The browser, QR code reader, or other program processing the URI opens the spender’s Bitcoin [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program on the URI. If the [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program is aware of the [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/), it accesses the URL specified in the [“r”](https://developer.bitcoin.org/terms.html#term-r-parameter) parameter, which should provide it with a serialized [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) served with the [MIME](https://en.wikipedia.org/wiki/Internet_media_type) type `application/bitcoin-paymentrequest`.

**Resource:** Gavin Andresen’s [Payment Request Generator](https://github.com/gavinandresen/paymentrequest/blob/master/php/demo_website/createpaymentrequest.php) generates custom example URIs and payment requests for use with [Testnet](https://bitcoindevelopers.org/encyclopedia/testnet/).

### PaymentRequest & PaymentDetails[https://developer.bitcoin.org/examples/payment_processing.html#paymentrequest-paymentdetails](https://developer.bitcoin.org/examples/payment_processing.html#paymentrequest-paymentdetails)

The [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) is created with data structures built using Google’s [Protocol Buffers](https://developers.google.com/protocol-buffers/). [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) describes these data structures in the non-sequential way they’re defined in the [Payment request](https://bitcoindevelopers.org/encyclopedia/payment-request/) [protocol buffer](https://developers.google.com/protocol-buffers/) code, but the text below will describe them in a more linear order using a simple (but functional) Python CGI program. (For brevity and clarity, many normal CGI best practices are not used in this program.)

The full sequence of events is illustrated below, starting with the spender clicking a [“bitcoin:” URI](https://developer.bitcoin.org/terms.html#term-bitcoin-uri) or scanning a `bitcoin:` QR code.

![BIP70 Payment Protocol](https://developer.bitcoin.org/_images/en-payment-protocol.svg)

BIP70 [Payment protocol](https://bitcoindevelopers.org/encyclopedia/payment-protocol/)[https://developer.bitcoin.org/examples/payment_processing.html#id1](https://developer.bitcoin.org/examples/payment_processing.html#id1)

For the script to use the [protocol buffer](https://developers.google.com/protocol-buffers/), you will need a copy of Google’s [Protocol Buffer](https://developers.google.com/protocol-buffers/) compiler (`protoc`), which is available in most modern Linux package managers and [directly from Google.](https://developers.google.com/protocol-buffers/) Non-Google [protocol buffer](https://developers.google.com/protocol-buffers/) compilers are available for a variety of programming languages. You will also need a copy of the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) [Protocol Buffer description](https://github.com/bitcoin/bitcoin/blob/0.19/src/qt/paymentrequest.proto) from the Bitcoin Core source code.

#### Initialization Code[https://developer.bitcoin.org/examples/payment_processing.html#initialization-code](https://developer.bitcoin.org/examples/payment_processing.html#initialization-code)

With the Python code generated by `protoc`, we can start our simple CGI program.

```
#!/usr/bin/env python

## This is the code generated by protoc --python_out=./ [paymentrequest][paymentrequest].proto
from paymentrequest_pb2 import *

## Load some functions
from time import time
from sys import stdout
from OpenSSL.crypto import FILETYPE_PEM, load_privatekey, sign

## Copy three of the classes created by protoc into objects we can use
details = [PaymentDetails][paymentdetails]()
request = [PaymentRequest][paymentrequest]()
x509 = [x509certificates][x509certificates]()
```

The startup code above is quite simple, requiring nothing but the epoch (Unix date) time function, the standard out file descriptor, a few functions from the OpenSSL library, and the data structures and functions created by `protoc`.

#### Configuration Code[https://developer.bitcoin.org/examples/payment_processing.html#configuration-code](https://developer.bitcoin.org/examples/payment_processing.html#configuration-code)

Next, we’ll set configuration settings which will typically only change when the receiver wants to do something differently. The code pushes a few settings into the `request` ([PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest)) and `details` ([PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails)) objects. When we serialize them, [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails) will be contained within the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest).

```
## SSL Signature method
request.pki_type = "x509+sha256"  ## Default: none

## Mainnet or Testnet?
details.[network][network] = "test"  ## Default: main

## Postback URL
details.payment_url = "https://example.com/pay.py"

## [PaymentDetails][paymentdetails] version number
request.payment_details_version = 1  ## Default: 1

## [Certificate chain][Certificate chain]
x509.certificate.append(file("/etc/apache2/example.com-cert.[der][der]", "r").read())
#x509.certificate.append(file("/some/intermediate/cert.[der][der]", "r").read())

## Load private SSL key into memory for signing later
priv_key = "/etc/apache2/example.com-key.pem"
pw = "test"  ## Key password
private_key = load_privatekey(FILETYPE_PEM, file(priv_key, "r").read(), pw)
```

Each line is described below.

```
request.pki_type = "x509+sha256"  ## Default: none
```

[“pki_type”](https://developer.bitcoin.org/terms.html#term-pp-pki-type): (optional) tell the receiving [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program what [Public-Key Infrastructure](https://developer.bitcoin.org/terms.html#term-pki) ([PKI](https://developer.bitcoin.org/terms.html#term-pki)) type you’re using to cryptographically sign your [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) so that it can’t be modified by a [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) attack.

If you don’t want to sign the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest), you can choose a [“pki_type”](https://developer.bitcoin.org/terms.html#term-pp-pki-type) of `none` (the default).

If you do choose the sign the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest), you currently have two options defined by [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki): `x509+sha1` and `x509+sha256`. Both options use the [X.509](https://en.wikipedia.org/wiki/X.509) certificate system, the same system used for HTTP Secure (HTTPS). To use either option, you will need a certificate signed by a certificate authority or one of their intermediaries. (A self-signed certificate will not work.)

Each [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program may choose which certificate authorities to trust, but it’s likely that they’ll trust whatever certificate authorities their operating system trusts. If the [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program doesn’t have a full operating system, as might be the case for small hardware wallets, [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) suggests they use the [Mozilla Root Certificate Store](https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/). In general, if a certificate works in your web browser when you connect to your webserver, it will work for your [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest).

```
details.[network][network] = "test"  ## Default: main
```

`network`: (optional) tell the spender’s [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program what Bitcoin [network](https://developer.bitcoin.org/devguide/p2p_network.html) you’re using; [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) defines “main” for [Mainnet](https://bitcoindevelopers.org/encyclopedia/mainnet/) (actual payments) and “test” for [Testnet](https://bitcoindevelopers.org/encyclopedia/testnet/) (like [Mainnet](https://bitcoindevelopers.org/encyclopedia/mainnet/), but fake [Satoshis](https://bitcoindevelopers.org/encyclopedia/satoshis/) are used). If the [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program doesn’t run on the [network](https://developer.bitcoin.org/devguide/p2p_network.html) you indicate, it will reject the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest).

```
details.payment_url = "https://example.com/pay.py"
```

`payment_url`: (required) tell the spender’s [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program where to send the Payment [Message](https://bitcoindevelopers.org/encyclopedia/message/) (described later). This can be a static URL, as in this example, or a variable URL such as `https://example.com/pay.py?invoice=123.` It should usually be an HTTPS [Address](https://bitcoindevelopers.org/encyclopedia/address/) to prevent [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) attacks from modifying the [Message](https://bitcoindevelopers.org/encyclopedia/message/).

```
request.payment_details_version = 1  ## Default: 1
```

`payment_details_version`: (optional) tell the spender’s [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program what version of the [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails) you’re using. As of this writing, the only version is version 1.

```
## This is the pubkey/certificate corresponding to the private SSL key
## that we'll use to sign:
x509.certificate.append(file("/etc/apache2/example.com-cert.[der][der]", "r").read())
```

`x509certificates`: (required for signed [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest)) you must provide the public SSL key/certificate corresponding to the private SSL key you’ll use to sign the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest). The certificate must be in ASN.1/[DER format](https://en.wikipedia.org/wiki/X.690#DER_encoding).

```
## If the pubkey/cert above didn't have the Signature of a root
## certificate authority, we'd then append the [Intermediate certificate][Intermediate certificate]
## which signed it:
#x509.certificate.append(file("/some/intermediate/cert.[der][der]", "r").read())
```

You must also provide any [intermediate certificates](https://developer.bitcoin.org/terms.html#term-intermediate-certificate) necessary to link your certificate to the [root certificate](https://developer.bitcoin.org/terms.html#term-root-certificate) of a certificate authority trusted by the spender’s software, such as a certificate from the Mozilla root store.

The certificates must be provided in a specific order—the same order used by Apache’s `SSLCertificateFile` directive and other server software. The figure below shows the [certificate chain](https://developer.bitcoin.org/terms.html#term-certificate-chain) of the www.bitcoin.org [X.509](https://en.wikipedia.org/wiki/X.509) certificate and how each certificate (except the [root certificate](https://developer.bitcoin.org/terms.html#term-root-certificate)) would be loaded into the [X509Certificates](https://developer.bitcoin.org/terms.html#term-x509certificates) [protocol buffer](https://developers.google.com/protocol-buffers/) [Message](https://bitcoindevelopers.org/encyclopedia/message/).

![X509Certificates Loading Order](https://developer.bitcoin.org/_images/en-cert-order.svg)

[x509certificates](https://bitcoindevelopers.org/encyclopedia/x509certificates/) Loading Order[https://developer.bitcoin.org/examples/payment_processing.html#id2](https://developer.bitcoin.org/examples/payment_processing.html#id2)

To be specific, the first certificate provided must be the [X.509](https://en.wikipedia.org/wiki/X.509) certificate corresponding to the private SSL key which will make the [Signature](https://bitcoindevelopers.org/encyclopedia/signature/), called the [leaf certificate](https://developer.bitcoin.org/terms.html#term-leaf-certificate). Any [intermediate certificates](https://developer.bitcoin.org/terms.html#term-intermediate-certificate) necessary to link that signed public SSL key to the [root certificate](https://developer.bitcoin.org/terms.html#term-root-certificate) (the certificate authority) are attached separately, with each certificate in [DER format](https://en.wikipedia.org/wiki/X.690#DER_encoding) bearing the [Signature](https://bitcoindevelopers.org/encyclopedia/signature/) of the certificate that follows it all the way to (but not including) the [root certificate](https://developer.bitcoin.org/terms.html#term-root-certificate).

```
priv_key = "/etc/apache2/example.com-key.pem"
pw = "test"  ## Key password
private_key = load_privatekey(FILETYPE_PEM, file(priv_key, "r").read(), pw)
```

(Required for signed [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest)) you will need a private SSL key in a format your SSL library supports ([DER format](https://en.wikipedia.org/wiki/X.690#DER_encoding) is not required). In this program, we’ll load it from a PEM file. (Embedding your passphrase in your CGI code, as done here, is obviously a bad idea in real life.)

The private SSL key will not be transmitted with your request. We’re only loading it into memory here so we can use it to sign the request later.

#### Code Variables[https://developer.bitcoin.org/examples/payment_processing.html#code-variables](https://developer.bitcoin.org/examples/payment_processing.html#code-variables)

Now let’s look at the variables your CGI program will likely set for each payment.

```
## Amount of the request
amount = 10000000  ## In Satoshis

## P2PKH pubkey hash
pubkey_hash = "2b14950b8d31620c6cc923c5408a701b1ec0a020"
## P2PKH Pubkey script entered as hex and converted to binary
# OP_DUP OP_HASH160 <push 20 bytes> <pubKey hash> OP_EQUALVERIFY OP_CHECKSIG
#   76       a9            14       <pubKey hash>        88          ac
hex_script = "76" + "a9" + "14" + pubkey_hash + "88" + "ac"
serialized_script = hex_script.decode("hex")

## Load amount and Pubkey script into [PaymentDetails][paymentdetails]
details.outputs.add(amount = amount, script = serialized_script)

## Memo to display to the spender
details.memo = "Flowers & chocolates"

## Data which should be returned to you with the payment
details.merchant_data = "Invoice #123"
```

Each line is described below.

```
amount = 10000000  ## In Satoshis (=100 mBTC)
```

[“amount”](https://developer.bitcoin.org/terms.html#term-pp-amount): (optional) the [amount](https://developer.bitcoin.org/terms.html#term-pp-amount) you want the spender to pay. You’ll probably get this value from your shopping cart application or [fiat](https://developer.bitcoin.org/terms.html#term-fiat)-to-BTC exchange rate conversion tool. If you leave the amount blank, the [Wallet](https://bitcoindevelopers.org/encyclopedia/wallet/) program will prompt the spender how much to pay (which can be useful for donations).

```
pubkey_hash = "2b14950b8d31620c6cc923c5408a701b1ec0a020"
# OP_DUP OP_HASH160 <push 20 bytes> <pubKey hash> OP_EQUALVERIFY OP_CHECKSIG
#   76       a9            14       <pubKey hash>        88          ac
hex_script = "76" + "a9" + "14" + pubkey_hash + "88" + "ac"
serialized_script = hex_script.decode("hex")
```

[“script”](https://developer.bitcoin.org/terms.html#term-pp-script): (required) You must specify the [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/) you want the spender to pay—any valid [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/) is acceptable. In this example, we’ll request payment to a P2PKH [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/).

First we get a pubkey hash. The hash above is the hash form of the [Address](https://bitcoindevelopers.org/encyclopedia/address/) used in the URI examples throughout this section, mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN.

Next, we plug that hash into the standard P2PKH [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/) using hex, as illustrated by the code comments.

Finally, we convert the [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/) from hex into its serialized form.

```
details.outputs.add(amount = amount, script = serialized_script)
```

`outputs`: (required) add the [Pubkey script](https://bitcoindevelopers.org/encyclopedia/pubkey-script/) and (optional) amount to the [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails) outputs array.

It’s possible to specify multiple [“scripts”](https://developer.bitcoin.org/terms.html#term-pp-script) and `amounts` as part of a [merge avoidance](https://developer.bitcoin.org/terms.html#term-merge-avoidance) strategy, described later in the [Merge Avoidance subsection](https://developer.bitcoin.org/devguide/payment_processing.html#merge-avoidance). However, effective [merge avoidance](https://developer.bitcoin.org/terms.html#term-merge-avoidance) is not possible under the base [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) rules in which the spender pays each [“script”](https://developer.bitcoin.org/terms.html#term-pp-script) the exact amount specified by its paired [“amount”](https://developer.bitcoin.org/terms.html#term-pp-amount). If the amounts are omitted from all [“amount”](https://developer.bitcoin.org/terms.html#term-pp-amount)/[“script”](https://developer.bitcoin.org/terms.html#term-pp-script) pairs, the spender will be prompted to choose an amount to pay.

```
details.memo = "Flowers & chocolates"
```

[“memo”](https://developer.bitcoin.org/terms.html#term-pp-memo): (optional) add a memo which will be displayed to the spender as plain UTF-8 text. Embedded HTML or other markup will not be processed.

```
details.merchant_data = "Invoice #123"
```

[“merchant_data”](https://developer.bitcoin.org/terms.html#term-pp-merchant-data): (optional) add arbitrary data which should be sent back to the receiver when the invoice is paid. You can use this to track your invoices, although you can more reliably track payments by generating a [unique address](https://developer.bitcoin.org/terms.html#term-unique-address) for each payment and then tracking when it gets paid.

The [“memo”](https://developer.bitcoin.org/terms.html#term-pp-memo) field can be arbitrarily long, but if you make them too long, you’ll run into the 50,000 byte limit on the entire [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest), which includes the often several kilobytes given over to storing the [certificate chain](https://developer.bitcoin.org/terms.html#term-certificate-chain). As will be described in a later subsection, the [“memo”](https://developer.bitcoin.org/terms.html#term-pp-memo) field can be used by the spender after payment as part of a cryptographically-proven [receipt](https://developer.bitcoin.org/terms.html#term-receipt).

#### Derivable Data[https://developer.bitcoin.org/examples/payment_processing.html#derivable-data](https://developer.bitcoin.org/examples/payment_processing.html#derivable-data)

Next, let’s look at some information your CGI program can automatically derive.

```
## Request creation time
details.time = int(time()) ## Current epoch (Unix) time

## Request expiration time
details.expires = int(time()) + 60 * 10  ## 10 minutes from now

## [PaymentDetails][paymentdetails] is complete; serialize it and store it in [PaymentRequest][paymentrequest]
request.serialized_payment_details = details.SerializeToString()

## Serialized [Certificate chain][Certificate chain]
request.pki_data = x509.SerializeToString()

## Initialize Signature field so we can sign the full [PaymentRequest][paymentrequest]
request.Signature = ""

## Sign [PaymentRequest][paymentrequest]
request.Signature = sign(private_key, request.SerializeToString(), "sha256")
```

Each line is described below.

```
details.time = int(time()) ## Current epoch (Unix) time
```

`time`: (required) [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest) must indicate when they were created in number of seconds elapsed since 1970-01-01T00:00 UTC ([Unix epoch time](https://en.wikipedia.org/wiki/Unix_time) format).

```
details.expires = int(time()) + 60 * 10  ## 10 minutes from now
```

[“expires”](https://developer.bitcoin.org/terms.html#term-pp-expires): (optional) the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) may also set an [“expires”](https://developer.bitcoin.org/terms.html#term-pp-expires) time after which they’re no longer valid. You probably want to give receivers the ability to configure the expiration time delta; here we used the reasonable choice of 10 minutes. If this request is tied to an order total based on a [fiat](https://developer.bitcoin.org/terms.html#term-fiat)-to-[Satoshis](https://bitcoindevelopers.org/encyclopedia/satoshis/) exchange rate, you probably want to base this on a delta from the time you got the exchange rate.

```
request.serialized_payment_details = details.SerializeToString()
```

`serialized_payment_details`: (required) we’ve now set everything we need to create the [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails), so we’ll use the SerializeToString function from the [protocol buffer](https://developers.google.com/protocol-buffers/) code to store the [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails) in the appropriate field of the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest).

```
request.pki_data = x509.SerializeToString()
```

`pki_data`: (required for signed [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest)) serialize the [certificate chain](https://developer.bitcoin.org/terms.html#term-certificate-chain) [PKI data](https://developer.bitcoin.org/terms.html#term-pp-pki-data) and store it in the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest)

```
request.Signature = ""
```

We’ve filled out everything in the [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) except the [Signature](https://bitcoindevelopers.org/encyclopedia/signature/), but before we sign it, we have to initialize the [Signature](https://bitcoindevelopers.org/encyclopedia/signature/) field by setting it to a zero-byte placeholder.

```
request.Signature = sign(private_key, request.SerializeToString(), "sha256")
```

`Signature`: (required for signed [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest)) now we make the [signature](https://developer.bitcoin.org/terms.html#term-ssl-signature) by signing the completed and serialized [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest). We’ll use the [Private key](https://bitcoindevelopers.org/encyclopedia/private-key/) we stored in memory in the configuration section and the same hashing formula we specified in [“pki_type”](https://developer.bitcoin.org/terms.html#term-pp-pki-type) (sha256 in this case)

#### [Output](https://bitcoindevelopers.org/encyclopedia/output/) Code[https://developer.bitcoin.org/examples/payment_processing.html#output-code](https://developer.bitcoin.org/examples/payment_processing.html#output-code)

Now that we have [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) all filled out, we can serialize it and send it along with the HTTP headers, as shown in the code below.

```
print "Content-Type: application/bitcoin-[paymentrequest][paymentrequest]"
print "Content-Transfer-Encoding: binary"
print ""
```

(Required) [BIP71](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) defines the content types for [PaymentRequests](https://developer.bitcoin.org/terms.html#term-paymentrequest), Payments, and PaymentACKs.

```
file.write(stdout, request.SerializeToString())
```

`request`: (required) now, to finish, we just dump out the serialized [PaymentRequest](https://developer.bitcoin.org/terms.html#term-paymentrequest) (which contains the serialized [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails)). The serialized data is in binary, so we can’t use Python’s print() because it would add an extraneous newline.

The following screenshot shows how the authenticated [PaymentDetails](https://developer.bitcoin.org/terms.html#term-paymentdetails) created by the program above appears in the GUI from Bitcoin Core 0.9.

![Bitcoin Core Showing Validated Payment Request](https://developer.bitcoin.org/_images/en-btcc-payment-request.png)

Bitcoin Core Showing Validated [Payment request](https://bitcoindevelopers.org/encyclopedia/payment-request/)
